Python+Vue实现简单的前后端分离

准备工作

  1. 安装Node环境
  2. 安装Python环境

注意:项目整个过程需要从后往前,即先数据库->后端->前端;启动流程也是先启动后端项目,再启动前端项目
完整项目地址:地址

前端

开发工具:Visual Studio Code(推荐)、WebStorm

打开cmd,安装Vue脚手架,命令如下:

npm install -g @vue/cli

创建Vue2项目,名为 vue-axios

vue create vue-axios

选择 Manually select features进行创建,回车

Python+Vue实现简单的前后端分离
目前只勾选 Router,回车
Python+Vue实现简单的前后端分离
选择 2.x,回车
Python+Vue实现简单的前后端分离
选择如下,回车,等待下载依赖
Python+Vue实现简单的前后端分离
下载完成后,进入到项目内
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.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';

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

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)
        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

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组件:


    前后端分离小demo

          操作
          添加一条记录

          编辑

            删除

        重置
        确 定

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
                });
              }
            })
          }
        }
      })
    }
  }
}

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;
}

修改App.vue,如下:


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

其中 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/即可打开首页,默认查询全部数据,如下:

Python+Vue实现简单的前后端分离
添加页面:
Python+Vue实现简单的前后端分离
编辑页面:
Python+Vue实现简单的前后端分离
删除页面:
Python+Vue实现简单的前后端分离
基本的增删改查均已实现,全部采用接口请求的方式进行实现,在开发者工具的网络工具栏下,可以看到前端发送的请求,如下:
Python+Vue实现简单的前后端分离
以及后端响应数据的预览结果:
Python+Vue实现简单的前后端分离

后端

开发环境: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返回格式


class JsonResponse(object):

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

    @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, jsonify

from json_response import JsonResponse

class JsonFlask(Flask):
    def make_response(self, rv):

        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 pymysql

DB_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()

    def modify(self, sql, args=None):
        row = self.cursor.execute(sql, args)
        self.conn.commit()
        return row > 0

    def multi_modify(self, sql, args=None):
        rows = self.cursor.executemany(sql, args)
        self.conn.commit()
        return rows > 0

    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

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)
    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)
    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='删除失败')

if __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;

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;

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;

Original: https://blog.csdn.net/qq_45917176/article/details/125421084
Author: 杼蛘
Title: Python+Vue实现简单的前后端分离

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/672616/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球