一区二区日本_久久久久久久国产精品_无码国模国产在线观看_久久99深爱久久99精品_亚洲一区二区三区四区五区午夜_日本在线观看一区二区

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

目錄

準(zhǔn)備工作

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

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

前端

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

打開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)建,回車

目前只勾選Router,回車

選擇2.x,回車

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

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

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',  // 注意!! 這里是全局統(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 = 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>    <!-- 表格區(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 => {    // 判斷是否通過驗(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

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

npm run serve

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

添加頁面:

編輯頁面:

刪除頁面:

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

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

后端

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

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

pip install flask

安裝flask_cors庫,命令如下:

pip install flask_cors

安裝pymysql庫,命令如下:

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來傳遞當(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, jsonifyfrom json_response import JsonResponseclass 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ù)庫操作

# 數(shù)據(jù)庫操作類import pymysqlDB_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ù)庫	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語句	def modify(self, sql, args=None):		row = self.cursor.execute(sql, args)		self.conn.commit()		return row > 0	# 執(zhí)行多條SQL語句	def multi_modify(self, sql, args=None):		rows = self.cursor.executemany(sql, args)		self.conn.commit()		return rows > 0	# 關(guān)閉數(shù)據(jù)庫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# 創(chuàng)建視圖應(yīng)用app = JsonFlask(__name__)# 解決跨域CORS(app, supports_credentials=True)db = SQLManager()# 編寫視圖函數(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è)置端口為666if __name__ == '__main__':    app.run(host="0.0.0.0", port=666, debug=True)

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

數(shù)據(jù)庫

采用MySQL,由于是小demo,此處設(shè)計(jì)較簡(jiǎn)單,數(shù)據(jù)庫名為test,表名為user,表結(jié)構(gòu)和數(shù)據(jù)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;

總結(jié)

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

聲明:所有內(nèi)容來自互聯(lián)網(wǎng)搜索結(jié)果,不保證100%準(zhǔn)確性,僅供參考。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。
發(fā)表評(píng)論
更多 網(wǎng)友評(píng)論1 條評(píng)論)
暫無評(píng)論

返回頂部

主站蜘蛛池模板: 国产精品国产三级国产aⅴ中文 | 日韩成人精品在线观看 | 精品电影 | 国产成人精品一区二区三 | 成人区精品 | 久久久久国产一区二区三区 | 国产精品视频一区二区三区四蜜臂 | 99精品一区二区 | 日韩精品一二三区 | 成人免费观看视频 | 天天影视网天天综合色在线播放 | 五月天国产视频 | 一级在线观看 | 日韩欧美视频在线 | 国产精品亚洲一区二区三区在线观看 | 亚洲精品日日夜夜 | 国产成人精品一区二区三区视频 | 日韩中文字幕一区二区 | 免费同性女女aaa免费网站 | 日本污视频 | 日韩中文在线视频 | 亚洲播放 | 午夜免费视频 | 中文日韩在线 | 亚洲国产精品91 | 国产精品免费一区二区 | 一级a性色生活片久久毛片 午夜精品在线观看 | 在线看av网址 | 久久久一区二区三区四区 | 91欧美精品| 久久毛片 | 国产精品欧美精品 | 国产精品18久久久久久久 | 日韩精品一区二区三区在线观看 | 一区二区三区四区国产精品 | 波多野结衣精品 | 亚洲成人福利视频 | 天天插天天狠天天透 | 手机av在线 | 色婷婷精品久久二区二区蜜臂av | 一区二区三区视频在线 |