目录
准备工作前端后端数据库总结准备工作
安装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 = request
Vue.use(ElementUI);
new Vue({
router,
render: function (h) { return h(App) }
}).$mount("#app")
删除多余的组件,如在src/views和src/components下的vue组件;在src/views新建Home.vue组件:
<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>前后端分离小demo
操作 添加一条记录 编辑 删除 重置 确 定
修改App.vue,如下:
其中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, jsonify
from json_response import JsonResponse
class 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 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()
# 执行单条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 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) # 将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端口,此处设置端口为666
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; -- ---------------------------- -- 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实现前后端分离内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 1转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 2充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 3好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 4名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 5亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战
- 6京东绿色建材线上平台上线 新增用户70%来自下沉市场
- 7网红淘品牌“七格格”chuu在北京又开一家店 潮人新宠chuu能红多久
- 8市场竞争加剧,有车企因经营不善出现破产、退网、退市
- 9北京市市场监管局为企业纾困减负保护经济韧性
- 10市场监管总局发布限制商品过度包装标准和第1号修改单

(资料图片仅供参考)