如何利用Python+Vue實現簡單得前后端分離

    目錄

    準備工作

    • 安裝Node環境
    • 安裝Python環境

    注意:項目整個過程需要從后往前,即先數據庫->后端->前端;啟動流程也是先啟動后端項目,再啟動前端項目

    前端

    開發工具:Visual Studio Code(推薦)、WebStorm

    打開cmd,安裝Vue腳手架,命令如下:

    npm install -g @vue/cli

    創建Vue2項目,名為vue-axios

    vue create vue-axios

    選擇Manually select features進行創建,回車

    目前只勾選Router,回車

    選擇2.x,回車

    選擇如下,回車,等待下載依賴

    下載完成后,進入到項目內

    cd vue-axios

    安裝axios庫

    npm install axios --save

    安裝Element UI庫

    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',  // 注意!! 這里是全局統一加上了 后端接口前綴 前綴,后端必須進行跨域配置!    timeout: 5000})// request 攔截器// 可以自請求發送前對請求做一些處理// 比如統一加token,對請求參數統一加密request.interceptors.request.use(config => {    config.headers['Content-Type'] = 'application/json;charset=utf-8';    // config.headers['token'] = user.token;  // 設置請求頭    return config}, error => {    return Promise.reject(error)});// response 攔截器// 可以在接口響應后統一處理結果request.interceptors.response.use(    response => {        let res = response.data;        // 如果是返回得文件        if (response.config.responseType === 'blob') {            return res        }        // 兼容服務端返回得字符串數據        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,進行注冊

    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';// 關閉生產模式下得提示Vue.config.productionTip = false// 設置axios為Vue得原型屬性Vue.prototype.$axios = requestVue.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>    <!-- 表格區域 -->    <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="確認刪除嗎?"            @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() {    // 自定義驗證規則    var validateAge = (rule, value, callback) => {      if (value === '' || value === undefined) {        callback(new Error('請輸入年齡'))      } else if (isNaN(value)) {        callback(new Error('請輸入數字'))      } else if (value < 1 || value > 100) {        callback(new Error('年齡必須在1~100之間'))      } else {        callback()      }    }    return {      table: [],      dialogVisible: false,      title: '',      form: {},      rules: {        name: [{ required: true, message: '請輸入姓名', trigger: 'blur' }],        age: [{ required: true, validator: validateAge, trigger: 'blur' }],        sex: [{ required: true, message: '請選擇性別', 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 => {    // 判斷是否通過驗證        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: '錯誤',                  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: '錯誤',                  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

    打開終端或cmd,輸入如下命令啟動項目

    npm run serve

    在瀏覽器輸入http://localhost:8080/即可打開首頁,默認查詢全部數據,如下:

    添加頁面:

    編輯頁面:

    刪除頁面:

    基本得增刪改查均已實現,全部采用接口請求得方式進行實現,在開發者工具得網絡工具欄下,可以看到前端發送得請求,如下:

    以及后端響應數據得預覽結果:

    后端

    開發環境:PyCharm(推薦)、Visual Studio Code

    打開cmd,安裝flask庫,命令如下:

    pip install flask

    安裝flask_cors庫,命令如下:

    pip install flask_cors

    安裝pymysql庫,命令如下:

    pip install pymysql

    創建Python項目,名為python-flask

    新建json_response.py,統一json返回格式

    # 統一得json返回格式class JsonResponse(object):    def __init__(self, code, msg, data):        self.code = code        self.msg = msg        self.data = data    # 指定一個類得方法為類方法,通常用self來傳遞當前類得實例--對象,cls傳遞當前類。    @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對象

    from flask import Flask, jsonifyfrom json_response import JsonResponseclass JsonFlask(Flask):    def make_response(self, rv):        # 視圖函數可以直接返回: 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,數據庫操作

    # 數據庫操作類import pymysqlDB_CONFIG = {	"host": "127.0.0.1",	"port": 3306,	"user": "root",	"passwd": "123456",	"db": "test",	"charset": "utf8"}class SQLManager(object):	# 初始化實例方法	def __init__(self):		self.conn = None		self.cursor = None		self.connect()	# 連接數據庫	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)	# 查詢多條數據	def get_list(self, sql, args=None):		self.cursor.execute(sql, args)		return self.cursor.fetchall()	# 查詢單條數據	def get_one(self, sql, args=None):		self.cursor.execute(sql, args)		return self.cursor.fetchone()	# 執行單條SQL語句	def modify(self, sql, args=None):		row = self.cursor.execute(sql, args)		self.conn.commit()		return row > 0	# 執行多條SQL語句	def multi_modify(self, sql, args=None):		rows = self.cursor.executemany(sql, args)		self.conn.commit()		return rows > 0	# 關閉數據庫cursor和連接	def close(self):		self.cursor.close()		self.conn.close()

    新建app.py,主程序

    from flask import requestfrom flask_cors import *from json_flask import JsonFlaskfrom json_response import JsonResponsefrom config import *import json# 創建視圖應用app = JsonFlask(__name__)# 解決跨域CORS(app, supports_credentials=True)db = SQLManager()# 編寫視圖函數,綁定路由@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"])  # 添加(單個)def add():    data = json.loads(request.data)  # 將json字符串轉為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"])  # 修改(單個)def update():    data = json.loads(request.data)  # 將json字符串轉為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"])  # 刪除(單個)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='刪除失敗')# 運行flask:默認是5000端口,此處設置端口為666if __name__ == '__main__':    app.run(host="0.0.0.0", port=666, debug=True)

    啟動項目。

    數據庫

    采用MySQL,由于是小demo,此處設計較簡單,數據庫名為test,表名為user,表結構和數據SQL語句如下:

    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;

    總結

    到此這篇關于如何利用Python+Vue實現簡單得前后端分離得內容就介紹到這了,更多相關Python+Vue實現前后端分離內容請搜索之家以前得內容或繼續瀏覽下面得相關內容希望大家以后多多支持之家!

    聲明:所有內容來自互聯網搜索結果,不保證100%準確性,僅供參考。如若本站內容侵犯了原著者的合法權益,可聯系我們進行處理。
    發表評論
    更多 網友評論1 條評論)
    暫無評論

    返回頂部

    主站蜘蛛池模板: 精品女同一区二区三区免费播放 | 在线精品动漫一区二区无广告| 日本一区视频在线播放| 少妇人妻偷人精品一区二区| 另类ts人妖一区二区三区| 亚洲国产福利精品一区二区| 大屁股熟女一区二区三区| 国产精品资源一区二区| 激情亚洲一区国产精品| 久久亚洲综合色一区二区三区| 亚洲国产综合精品一区在线播放| 精品久久久久久中文字幕一区| 韩国福利影视一区二区三区| 中文字幕精品一区影音先锋| 亚洲一区二区三区高清| 国产精品毛片一区二区三区| 久久精品国产第一区二区| aⅴ一区二区三区无卡无码| 精品一区二区三区水蜜桃| 成人精品一区二区不卡视频| 国产精品亚洲一区二区麻豆 | 午夜视频在线观看一区二区| 在线精品一区二区三区| 中文字幕一区二区三匹| 久久久久人妻精品一区| 国产电影一区二区| 无码国产精品久久一区免费| 成人无码精品一区二区三区| 国产精品无码一区二区三区在| 国产在线一区二区三区av| 福利一区福利二区| 国产福利视频一区二区| 麻豆精品久久久一区二区| 亚洲午夜在线一区| 国产人妖视频一区二区破除| 无码人妻精品一区二| 九九久久99综合一区二区| 精品国产伦一区二区三区在线观看| 亚洲av无码一区二区三区观看 | 无码人妻精品一区二区三区99仓本| 秋霞日韩一区二区三区在线观看 |