欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何利用Python+Vue實(shí)現(xiàn)簡(jiǎn)單的前后端分離

 更新時(shí)間:2022年07月25日 12:34:45   作者:杼蛘  
因?yàn)閜ython開(kāi)發(fā)的高效性,python web開(kāi)發(fā)也受到越來(lái)越多人的關(guān)注,下面這篇文章主要給大家介紹了關(guān)于如何利用Python+Vue實(shí)現(xiàn)簡(jiǎn)單的前后端分離的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

準(zhǔn)備工作

  • 安裝Node環(huán)境
  • 安裝Python環(huán)境

注意:項(xiàng)目整個(gè)過(guò)程需要從后往前,即先數(shù)據(jù)庫(kù)->后端->前端;啟動(dòng)流程也是先啟動(dòng)后端項(xiàng)目,再啟動(dòng)前端項(xiàng)目

前端

開(kāi)發(fā)工具:Visual Studio Code(推薦)、WebStorm

打開(kāi)cmd,安裝Vue腳手架,命令如下:

npm install -g @vue/cli

創(chuàng)建Vue2項(xiàng)目,名為vue-axios

vue create vue-axios

選擇Manually select features進(jìn)行創(chuàng)建,回車(chē)

目前只勾選Router,回車(chē)

選擇2.x,回車(chē)

選擇如下,回車(chē),等待下載依賴

下載完成后,進(jìn)入到項(xiàng)目?jī)?nèi)

cd vue-axios

安裝axios庫(kù)

npm install axios --save

安裝Element UI庫(kù)

npm i element-ui -S

在src下新建utils文件夾,將request.js放于src/utils/下,request.js是axios的二次封裝,如下:

import axios from 'axios'

const request = axios.create({
    baseURL: 'http://127.0.0.1:666',  // 注意??! 這里是全局統(tǒng)一加上了 后端接口前綴 前綴,后端必須進(jìn)行跨域配置!
    timeout: 5000
})

// request 攔截器
// 可以自請(qǐng)求發(fā)送前對(duì)請(qǐng)求做一些處理
// 比如統(tǒng)一加token,對(duì)請(qǐng)求參數(shù)統(tǒng)一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';

    // config.headers['token'] = user.token;  // 設(shè)置請(qǐng)求頭

    return config
}, error => {
    return Promise.reject(error)
});

// response 攔截器
// 可以在接口響應(yīng)后統(tǒng)一處理結(jié)果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服務(wù)端返回的字符串?dāng)?shù)據(jù)
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)

export default request

修改main.js,進(jìn)行注冊(cè)

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import request from "@/utils/request"
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

// 關(guān)閉生產(chǎn)模式下的提示
Vue.config.productionTip = false

// 設(shè)置axios為Vue的原型屬性
Vue.prototype.$axios = request

Vue.use(ElementUI);

new Vue({
  router,
  render: function (h) { return h(App) }
}).$mount('#app')

刪除多余的組件,如在src/views和src/components下的vue組件;在src/views新建Home.vue組件:

<template>
  <div class="home">
    <h1>前后端分離小demo</h1>

    <!-- 表格區(qū)域 -->
    <el-table
      :data="table"
      stripe
      :cell-style="{ textAlign: 'center' }"
      :header-cell-style="{ textAlign: 'center' }"
    >
      <el-table-column prop="id" label="ID" width="100" sortable />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="age" label="年齡" />
      <el-table-column prop="sex" label="性別" />

      <el-table-column label="操作" width="210">
        <template slot="header">
          <span class="op">操作</span>
          <el-button size="mini" class="add" @click="add" icon="el-icon-plus"
            >添加一條記錄</el-button
          >
        </template>
        <template slot-scope="scope">
          <el-button
            type="info"
            size="mini"
            @click="handEdit(scope.$index, scope.row)"
            icon="el-icon-edit"
            round
            >編輯</el-button
          >
          <el-popconfirm
            title="確認(rèn)刪除嗎?"
            @confirm="handDelete(scope.$index, scope.row)"
          >
            <el-button
              type="danger"
              size="mini"
              icon="el-icon-delete"
              round
              slot="reference"
              >刪除</el-button
            >
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <!-- 彈出窗 -->
    <el-dialog
      :title="title"
      :visible="dialogVisible"
      width="30%"
      :before-close="handleClose"
    >
      <el-form
        :model="form"
        status-icon
        :rules="rules"
        ref="form"
        label-width="60px"
      >
        <el-form-item label="姓名" prop="name">
          <el-input v-model="form.name" autocomplete="off" />
        </el-form-item>
        <el-form-item label="年齡" prop="age">
          <el-input
            type="number"
            min="1"
            max="99"
            v-model="form.age"
            autocomplete="off"
          />
        </el-form-item>
        <el-form-item label="性別" prop="sex">
          <el-radio-group v-model="form.sex">
            <el-radio label="男"></el-radio>
            <el-radio label="女"></el-radio>
            <el-radio label="未知"></el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="reset">重置</el-button>
        <el-button type="primary" @click="save">確 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>

export default {
  name: 'Home',
  data() {
    // 自定義驗(yàn)證規(guī)則
    var validateAge = (rule, value, callback) => {
      if (value === '' || value === undefined) {
        callback(new Error('請(qǐng)輸入年齡'))
      } else if (isNaN(value)) {
        callback(new Error('請(qǐng)輸入數(shù)字'))
      } else if (value < 1 || value > 100) {
        callback(new Error('年齡必須在1~100之間'))
      } else {
        callback()
      }
    }
    return {
      table: [],
      dialogVisible: false,
      title: '',
      form: {},
      rules: {
        name: [{ required: true, message: '請(qǐng)輸入姓名', trigger: 'blur' }],
        age: [{ required: true, validator: validateAge, trigger: 'blur' }],
        sex: [{ required: true, message: '請(qǐng)選擇性別', trigger: 'blur' }],
      }
    }
  },
  created() {
    this.init()
  },
  methods: {
    init() {
      this.$axios.get('/all').then(res => {
        console.log(res);
        this.table = res.data
      })
    },
    add() {
      this.dialogVisible = true
      this.title = '添加記錄'
      this.form = {}
    },
    handEdit(index, row) {
      this.dialogVisible = true
      this.title = '編輯記錄'
      this.form = JSON.parse(JSON.stringify(row))
    },
    handDelete(index, row) {
      let id = JSON.parse(JSON.stringify(row)).id
      this.$axios.delete(`/delete?id=${id}`).then(res => {
        if (res.code == 200) {
          this.$notify.success({
            title: '成功',
            message: res.msg,
            duration: 2000
          })
          this.init()
        } else {
          this.$notify.success({
            title: '失敗',
            message: res.msg,
            duration: 2000
          })
        }
      })
    },
    handleClose() {
      this.dialogVisible = false
      this.init()
    },
    reset() {
      let id = undefined
      if ('id' in this.form) {
        id = this.form.id
      }
      this.form = {}
      if (id != undefined) this.form.id = id
    },
    save() {
      this.$refs['form'].validate(valid => {    // 判斷是否通過(guò)驗(yàn)證
        if (valid) {
          console.log(this.form);
          if ('id' in this.form) {
            // console.log('修改');

            this.$axios.put('/update', this.form).then(res => {
              if (res.code == 200) {
                let _this = this
                this.$notify.success({
                  title: '成功',
                  message: res.msg,
                  duration: 2000,
                  onClose: function () { _this.handleClose() }
                });
              } else {
                this.$notify.error({
                  title: '錯(cuò)誤',
                  message: res.msg,
                  duration: 2000
                });
              }
            })

          } else {
            // console.log('添加');

            this.$axios.post('/add', this.form).then(res => {
              if (res.code == 200) {
                let _this = this
                this.$notify.success({
                  title: '成功',
                  message: res.msg,
                  duration: 2000,
                  onClose: function () { _this.handleClose() }
                });
              } else {
                this.$notify.error({
                  title: '錯(cuò)誤',
                  message: res.msg,
                  duration: 2000
                });
              }
            })
          }
        }
      })
    }
  }
}
</script>

<style>
h1 {
  text-align: center;
  margin: 50px 0;
}
.el-table {
  width: 60% !important;
  margin: 0 auto;
}
.el-button {
  margin: 0 5px;
}
span.op {
  display: inline-block;
  margin-left: 6px;
}
.el-dialog__body {
  padding-bottom: 0;
}
</style>

修改App.vue,如下:

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<style>
/* 引入外部css */
@import "./assets/css/reset.css";
</style>

其中reset.css如下:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

修改src/router/index.js如下:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: () => import('@/views/Home.vue')
  },
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

打開(kāi)終端或cmd,輸入如下命令啟動(dòng)項(xiàng)目

npm run serve

在瀏覽器輸入http://localhost:8080/即可打開(kāi)首頁(yè),默認(rèn)查詢?nèi)繑?shù)據(jù),如下:

添加頁(yè)面:

編輯頁(yè)面:

刪除頁(yè)面:

基本的增刪改查均已實(shí)現(xiàn),全部采用接口請(qǐng)求的方式進(jìn)行實(shí)現(xiàn),在開(kāi)發(fā)者工具的網(wǎng)絡(luò)工具欄下,可以看到前端發(fā)送的請(qǐng)求,如下:

以及后端響應(yīng)數(shù)據(jù)的預(yù)覽結(jié)果:

后端

開(kāi)發(fā)環(huán)境:PyCharm(推薦)、Visual Studio Code

打開(kāi)cmd,安裝flask庫(kù),命令如下:

pip install flask

安裝flask_cors庫(kù),命令如下:

pip install flask_cors

安裝pymysql庫(kù),命令如下:

pip install pymysql

創(chuàng)建Python項(xiàng)目,名為python-flask

新建json_response.py,統(tǒng)一json返回格式

# 統(tǒng)一的json返回格式

class JsonResponse(object):

    def __init__(self, code, msg, data):
        self.code = code
        self.msg = msg
        self.data = data

    # 指定一個(gè)類的方法為類方法,通常用self來(lái)傳遞當(dāng)前類的實(shí)例--對(duì)象,cls傳遞當(dāng)前類。
    @classmethod
    def success(cls, code=200, msg='success', data=None):
        return cls(code, msg, data)

    @classmethod
    def fail(cls, code=400, msg='fail', data=None):
        return cls(code, msg, data)

    def to_dict(self):
        return {
            "code": self.code,
            "msg": self.msg,
            "data": self.data
        }

新建json_flask.py,使flask支持返回JsonResponse對(duì)象

from flask import Flask, jsonify

from json_response import JsonResponse

class JsonFlask(Flask):
    def make_response(self, rv):
        # 視圖函數(shù)可以直接返回: list、dict、None
        if rv is None or isinstance(rv, (list, dict)):
            rv = JsonResponse.success(rv)

        if isinstance(rv, JsonResponse):
            rv = jsonify(rv.to_dict())

        return super().make_response(rv)

新建config.py,數(shù)據(jù)庫(kù)操作

# 數(shù)據(jù)庫(kù)操作類

import pymysql

DB_CONFIG = {
	"host": "127.0.0.1",
	"port": 3306,
	"user": "root",
	"passwd": "123456",
	"db": "test",
	"charset": "utf8"
}

class SQLManager(object):

	# 初始化實(shí)例方法
	def __init__(self):
		self.conn = None
		self.cursor = None
		self.connect()

	# 連接數(shù)據(jù)庫(kù)
	def connect(self):
		self.conn = pymysql.connect(
			host=DB_CONFIG["host"],
			port=DB_CONFIG["port"],
			user=DB_CONFIG["user"],
			passwd=DB_CONFIG["passwd"],
			db=DB_CONFIG["db"],
			charset=DB_CONFIG["charset"]
		)
		self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

	# 查詢多條數(shù)據(jù)
	def get_list(self, sql, args=None):
		self.cursor.execute(sql, args)
		return self.cursor.fetchall()

	# 查詢單條數(shù)據(jù)
	def get_one(self, sql, args=None):
		self.cursor.execute(sql, args)
		return self.cursor.fetchone()

	# 執(zhí)行單條SQL語(yǔ)句
	def modify(self, sql, args=None):
		row = self.cursor.execute(sql, args)
		self.conn.commit()
		return row > 0

	# 執(zhí)行多條SQL語(yǔ)句
	def multi_modify(self, sql, args=None):
		rows = self.cursor.executemany(sql, args)
		self.conn.commit()
		return rows > 0

	# 關(guān)閉數(shù)據(jù)庫(kù)cursor和連接
	def close(self):
		self.cursor.close()
		self.conn.close()

新建app.py,主程序

from flask import request
from flask_cors import *

from json_flask import JsonFlask
from json_response import JsonResponse
from config import *

import json

# 創(chuàng)建視圖應(yīng)用
app = JsonFlask(__name__)

# 解決跨域
CORS(app, supports_credentials=True)

db = SQLManager()

# 編寫(xiě)視圖函數(shù),綁定路由
@app.route("/all", methods=["GET"])  # 查詢(全部)
def all():
    result = db.get_list(sql='select * from user')
    return JsonResponse.success(msg='查詢成功', data=result)

@app.route("/add", methods=["POST"])  # 添加(單個(gè))
def add():
    data = json.loads(request.data)  # 將json字符串轉(zhuǎn)為dict
    isOk = db.modify(sql='insert into user(name,age,sex) values(%s,%s,%s)',
                      args=[data['name'], data['age'], data['sex']])
    return JsonResponse.success(msg='添加成功') if isOk else JsonResponse.fail(msg='添加失敗')

@app.route("/update", methods=["PUT"])  # 修改(單個(gè))
def update():
    data = json.loads(request.data)  # 將json字符串轉(zhuǎn)為dict
    if 'id' not in data:
        return JsonResponse.fail(msg='需要傳入id')
    isOk = db.modify(sql='update user set name=%s,age=%s,sex=%s where id=%s',
                      args=[data['name'], data['age'], data['sex'], data['id']])
    return JsonResponse.success(msg='修改成功') if isOk else JsonResponse.fail(msg='修改失敗')

@app.route("/delete", methods=["DELETE"])  # 刪除(單個(gè))
def delete():
    if 'id' not in request.args:
        return JsonResponse.fail(msg='需要傳入id')
    isOk = db.modify(sql='delete from user where id=%s', args=[request.args['id']])
    return JsonResponse.success(msg='刪除成功') if isOk else JsonResponse.fail(msg='刪除失敗')

# 運(yùn)行flask:默認(rèn)是5000端口,此處設(shè)置端口為666
if __name__ == '__main__':
    app.run(host="0.0.0.0", port=666, debug=True)

啟動(dòng)項(xiàng)目。

數(shù)據(jù)庫(kù)

采用MySQL,由于是小demo,此處設(shè)計(jì)較簡(jiǎn)單,數(shù)據(jù)庫(kù)名為test,表名為user,表結(jié)構(gòu)和數(shù)據(jù)SQL語(yǔ)句如下:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL,
  `age` int(11) NOT NULL,
  `sex` varchar(255) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = gbk COLLATE = gbk_chinese_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'tom', 20, '男');
INSERT INTO `user` VALUES (2, 'mary', 20, '女');
INSERT INTO `user` VALUES (3, 'jack', 21, '男');
INSERT INTO `user` VALUES (5, 'test', 20, '未知');
INSERT INTO `user` VALUES (8, 'tom', 20, '男');
INSERT INTO `user` VALUES (9, 'add', 20, '未知');
INSERT INTO `user` VALUES (10, 'Saly', 11, '女');

SET FOREIGN_KEY_CHECKS = 1;

總結(jié)

到此這篇關(guān)于如何利用Python+Vue實(shí)現(xiàn)簡(jiǎn)單的前后端分離的文章就介紹到這了,更多相關(guān)Python+Vue實(shí)現(xiàn)前后端分離內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python中asyncio模塊的深入講解

    Python中asyncio模塊的深入講解

    這篇文章主要給大家介紹了關(guān)于Python中asyncio模塊的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Python遞歸函數(shù) 二分查找算法實(shí)現(xiàn)解析

    Python遞歸函數(shù) 二分查找算法實(shí)現(xiàn)解析

    這篇文章主要介紹了Python遞歸函數(shù) 二分查找算法實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 在主機(jī)商的共享服務(wù)器上部署Django站點(diǎn)的方法

    在主機(jī)商的共享服務(wù)器上部署Django站點(diǎn)的方法

    這篇文章主要介紹了在主機(jī)商的共享服務(wù)器上部署Django站點(diǎn)的方法,Django是最具人氣的Python框架,需要的朋友可以參考下
    2015-07-07
  • Python編程pygal繪圖實(shí)例之XY線

    Python編程pygal繪圖實(shí)例之XY線

    這篇文章主要介紹了Python編程pygal繪圖實(shí)例之XY線,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • 理解python正則表達(dá)式

    理解python正則表達(dá)式

    這篇文章主要介紹了python正則表達(dá)式,在python中,對(duì)正則表達(dá)式的支持是通過(guò)re模塊來(lái)支持的,想要了解python正則表達(dá)式的朋友可以參考一下
    2016-01-01
  • Tornado協(xié)程在python2.7如何返回值(實(shí)現(xiàn)方法)

    Tornado協(xié)程在python2.7如何返回值(實(shí)現(xiàn)方法)

    下面小編就為大家?guī)?lái)一篇Tornado協(xié)程在python2.7如何返回值(實(shí)現(xiàn)方法)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Python中的sys模塊、random模塊和math模塊

    Python中的sys模塊、random模塊和math模塊

    這篇文章介紹了Python中的sys模塊、random模塊和math模塊,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • Python實(shí)現(xiàn)制度轉(zhuǎn)換(貨幣,溫度,長(zhǎng)度)

    Python實(shí)現(xiàn)制度轉(zhuǎn)換(貨幣,溫度,長(zhǎng)度)

    這篇文章主要介紹了Python實(shí)現(xiàn)制度轉(zhuǎn)換(貨幣,溫度,長(zhǎng)度),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • python使用Matplotlib改變坐標(biāo)軸的默認(rèn)位置

    python使用Matplotlib改變坐標(biāo)軸的默認(rèn)位置

    這篇文章主要為大家詳細(xì)介紹了python使用Matplotlib改變坐標(biāo)軸的默認(rèn)位置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 詳解Python中如何添加Selenium WebDriver等待

    詳解Python中如何添加Selenium WebDriver等待

    Selenium Web 驅(qū)動(dòng)程序提供兩種類型的等待, 第一個(gè)是隱式等待,第二個(gè)是顯式等待,本文主要為大家介紹了Python如何在Selenium Web驅(qū)動(dòng)程序中添加這兩種等待,需要的可以參考下
    2023-11-11

最新評(píng)論