目录
1 效果
1.1 查询所有用户
1.2 添加新用户
1.3 删除用户
1.4 用户详情
2 后端
2.1 查询所有
2.2 添加
2.3 删除
2.4 查询单个
3 前端
3.1 环境
3.2 main.js
3.3 userList.vue
3.4 userInfo.vue
1 效果
1.1 查询所有用户
1.2 添加新用户
如果点击取消就会显示添加失败
1.3 删除用户
点击取消会显示删除失败
点击确定会显示删除成功
1.4 用户详情
2 后端
pymysql一直开着会有一些问题,只能在每一次查询进行一次启停,每一个视图中写一遍就很麻烦,所以用到了请求钩子
from flask import Flask,request
import pymysql
import jsonapp = Flask(__name__)@app.before_request
def before_request():global connconn = pymysql.connect(host='127.0.0.1',user='root',password='12345678',database='my_db_01',charset='utf8')@app.after_request
def after_request(response):conn.commit()conn.close()return response@app.route('/get_users')
def get_users():cursor = conn.cursor()sql = 'SELECT * FROM my_db_01.element_ui_users'cursor.execute(sql)datas = cursor.fetchall()cursor.close()return_results = []for data in datas:results_obj = {}results_obj.__setitem__('id', data[0])results_obj.__setitem__('username', data[1])results_obj.__setitem__('age', data[2])results_obj.__setitem__('position', data[3])results_obj.__setitem__('create_time', data[4])return_results.append(results_obj)return json.dumps(return_results,ensure_ascii=False)@app.route('/get_one_user')
def get_one_user():id = request.args['id']cursor = conn.cursor()sql = 'SELECT * FROM my_db_01.element_ui_users where id=' + idcursor.execute(sql)datas = cursor.fetchall()cursor.close()for data in datas:results_obj = {}results_obj.__setitem__('id', data[0])results_obj.__setitem__('username', data[1])results_obj.__setitem__('age', data[2])results_obj.__setitem__('position', data[3])results_obj.__setitem__('create_time', data[4])return json.dumps(results_obj,ensure_ascii=False)@app.route('/add_user')
def add_user():username = request.args['username']age = request.args['age']position = request.args['position']create_time = request.args['create_time']cursor = conn.cursor()sql = "insert into my_db_01.element_ui_users (username,age,position,create_time) values ('{}',{},{},'{}')".format(username,age,position,create_time)cursor.execute(sql)cursor.close()return json.dumps({'status':0,'message':'添加成功'},ensure_ascii=False)@app.route('/delete_user')
def delete_user():id = request.args['id']cursor = conn.cursor()sql = "delete from my_db_01.element_ui_users where id={}".format(id)cursor.execute(sql)cursor.close()return json.dumps({'status':0,'message':'删除成功'},ensure_ascii=False)if __name__ == '__main__':app.run()
2.1 查询所有
2.2 添加
2.3 删除
2.4 查询单个
3 前端
3.1 环境
3.2 main.js
main.js主要解决了三个问题
- ElementUI
- axios
- vue-router
import { createApp } from 'vue'
import App from './App.vue'
import userInfo from '@/components/userInfo'
import userList from '@/components/userList'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import axios from 'axios'
import {createRouter,createWebHashHistory} from 'vue-router'// 解决 ElTable 自动宽度高度导致的「ResizeObserver loop limit exceeded」问题,参考链接 https://blog.csdn.net/weixin_41296877/article/details/130675694
const debounce = (fn, delay) => {let timer = null;return function () {let context = this;let args = arguments;clearTimeout(timer);timer = setTimeout(function () {fn.apply(context, args);}, delay);}}const _ResizeObserver = window.ResizeObserver;window.ResizeObserver = class ResizeObserver extends _ResizeObserver{constructor(callback) {callback = debounce(callback, 16);super(callback);}}// axios请求部分
// axios.defaults.baseURL = 'http://127.0.0.1:5000'
axios.defaults.baseURL = 'http://localhost:8080'// 路由部分
const router = createRouter({history:createWebHashHistory(),routes:[{path:'/',redirect:'/userList'},{path:'/userList',component:userList},{path:'/userInfo/:id',component:userInfo,props:true}]
})const app = createApp(App)
app.use(ElementPlus)
app.config.globalProperties.$http = axios
app.use(router)
app.mount('#app')
3.3 userList.vue
<template><!-- 按钮 --><el-button type="primary" style="margin-bottom: 20px;" @click="dialogFormVisible = true" >添加新用户</el-button><!-- 表格 --><el-table :data="userList" border stripe style="width: 100%"><el-table-column type="index" label="#" /><el-table-column prop="username" label="姓名" /><el-table-column prop="age" label="年龄" /><el-table-column prop="position" label="头衔" /><el-table-column label="创建时间"><template #default="scope">{{ format_time(scope.row.create_time) }}</template></el-table-column><el-table-column label="操作"><template #default="scope"><div><router-link :to="'/userInfo/'+scope.row.id">详情</router-link> <a href="javascript:void(0)" :delete_user_id="scope.row.id" @click="delete_user(scope.row.id)">删除</a></div></template></el-table-column></el-table><!-- 提示框 --><el-dialog v-model="dialogFormVisible" title="添加新用户" @close="dialogClose()"><el-form :model="add_user_form" :rules="add_user_form_rules" ref="add_user_form"><el-form-item label="用户姓名" :label-width="formLabelWidth" prop="username"><el-input v-model="add_user_form.username" autocomplete="off"/></el-form-item><el-form-item label="用户年龄" :label-width="formLabelWidth" prop="age"><el-input v-model.number="add_user_form.age" autocomplete="off" /></el-form-item><el-form-item label="用户头衔" :label-width="formLabelWidth" prop="position"><el-input v-model="add_user_form.position" autocomplete="off" /></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="dialogFormVisible = false">取消</el-button><el-button type="primary" @click="add_user();">确认</el-button></span></template></el-dialog></template><script>
import { ElMessage, ElMessageBox } from 'element-plus'export default {name: 'userList',data() {return {userList: [],add_user_form: {username: '',age: '',position: '',create_time: new Date()},dialogFormVisible: false,formLabelWidth: '100px',add_user_form_rules: {username: [{ required: true, message: '请输入名称', trigger: 'blur' },{ min: 1, max: 15, message: '最小长度为1,最大长度为15', trigger: 'blur' },],age: [{ required: true, message: '请输入名称', trigger: 'blur' },{ validator:this.checkAge,trigger:'blur' }],position: [{ required: true, message: '请输入头衔', trigger: 'blur' },{ min: 1, max: 10, message: '最小长度为1,最大长度为10', trigger: 'blur' },],}}},methods: {get_users() {this.$http.get('/get_users').then((res) =>{this.userList=res.data})},format_time(unformat_time) {const dt = new Date(unformat_time)const year = dt.getFullYear()const month = (dt.getMonth() + 1) > 9 ? (dt.getMonth() + 1) : '0' + (dt.getMonth() + 1)const day = (dt.getDate()) > 9 ? (dt.getDate()) : '0' + (dt.getDate())const hour = (dt.getHours()) > 9 ? (dt.getHours()) : '0' + (dt.getHours())const minute = (dt.getMinutes()) > 9 ? (dt.getMinutes()) : '0' + (dt.getMinutes())const second = (dt.getSeconds()) > 9 ? (dt.getSeconds()) : '0' + (dt.getSeconds())return `${year}-${month}-${day} ${hour}:${minute}:${second}`},add_user() {this.$refs.add_user_form.validate((valid)=>{if (valid) {ElMessageBox.confirm('是否添加新用户?','提示',{confirmButtonText: '确定',cancelButtonText: '取消',// type: 'info',// center: true,}).then(() => {this.$http.get('/add_user',{params:this.add_user_form}).then(()=>{this.get_users()this.dialogFormVisible = false})ElMessage({type: 'success',message: '添加成功',})}).catch(() => {ElMessage({type: 'info',message: '添加失败',})})}})},delete_user(delete_user_id) {ElMessageBox.confirm('此操作将永久删除该用户,是否继续?','提示',{confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning',// center: true,}).then(() => {this.$http.get('/delete_user',{params:{id:delete_user_id}}).then(()=>{this.get_users()this.dialogFormVisible = false})ElMessage({type: 'success',message: '删除成功',})}).catch(() => {ElMessage({type: 'info',message: '删除失败',})})},checkAge(rule,value,callback) {if (!value) {return callback(new Error('年龄是必填项'))}if (!Number.isInteger(value)) {return callback(new Error('你需要填写整数数字'))}if (value<1 || value>150) {return callback(new Error('年龄的值应在1-150之间'))}callback()},dialogClose() {this.$refs.add_user_form.resetFields()}},created() {this.get_users()}
}
</script><style scoped>
.el-input {width: 95%;height: 40px;
}
</style>
3.4 userInfo.vue
<template><el-card class="box-card"><template #header><div class="card-header"><span>用户详情</span><el-button class="button" text @click="this.$router.push('/userList')">返回</el-button></div></template><div class="text item">姓名 {{ username }}</div><div class="text item">年龄 {{ age }}</div><div class="text item">头衔 {{ position }}</div></el-card></template><script>export default {props:['id'],data() {return {username:'',age:'',position:''}},methods:{get_one_user() {this.$http.get('/get_one_user',{params:{id:this.id}}).then((res) =>{this.username=res.data.usernamethis.age=res.data.agethis.position=res.data.position})},},created() {this.get_one_user()}}
</script><style>
.card-header {display: flex;justify-content: space-between;align-items: center;
}.text {font-size: 14px;
}.item {margin-bottom: 18px;
}
</style>