<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
注意:專案整個過程需要從後往前,即先資料庫->後端->前端;啟動流程也是先啟動後端專案,再啟動前端專案
開發工具: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
元件:
<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, 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實現前後端分離內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45