您现在的位置是:首页 > 正文

附录7-用户列表案例,element-ui

2024-01-30 21:40:27阅读 0

目录

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 json

app = Flask(__name__)

@app.before_request
def before_request():
    global conn
    conn = 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=' + id
    cursor.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>&nbsp;
            <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.username
                    this.age=res.data.age
                    this.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>

网站文章

  • (Medium) Teemo Attacking - LeetCode

    Description:In LOL world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned condition. Now, given the Teemo's attacking ascending time series towards Ashe ...

    2024-01-30 21:39:59
  • SpringMVC中@ModelAttribute和@SessionAttributes注解的使用

    SpringMVC中@ModelAttribute和@SessionAttributes注解的使用

    1.@ModelAttribute注解的使用@ModelAttribute注解在两种地方可以使用从这里我们可以看到该注解可以用在参数上也可以用在方法体上。现在我们就来讲解这两种方式。方式一,该注解用在方法体上:在方法定义上使用 @ModelAttribute 注解:Spring MVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方...

    2024-01-30 21:39:52
  • linux基础命令-rm 最新发布

    在 Linux 操作系统中,rm 是一个强大的命令,用于删除文件和目录。它允许用户在文件系统中进行清理和维护操作,但同时也需要谨慎使用,因为删除的文件和目录不可恢复。在使用 rm 命令时,请注意核实您...

    2024-01-30 21:39:44
  • c++语言将字符串逆序输出,C++实现string类字符串单词的逆序输出

    c++语言将字符串逆序输出,C++实现string类字符串单词的逆序输出

    利用c++实现string类字符串单词的逆序输出,并改变源字符串的大小写。#include#include#includeusing namespace std;string StringReverseWord(string &s){int len = s.length();if (len == 0)//空字符串return s;int n = 0;while (s[n++] == ' '...

    2024-01-30 21:39:14
  • jep290涉及jdk版本_JDK 12 – JEP 325开关表达式

    jep290涉及jdk版本 JDK 12已于2019年3月19 日上线GA,继续致力于缩短发布周期和频繁发布。 该版本的功能部分可以在这里找到。 对于开发人员来说,有趣的功能之一是“ JEP 325开关表达式 ”,它可以作为预览功能使用。 此处定义的预览功能是: 预览语言或VM功能是Java SE平台的一项新功能,该功能已完全指定,完全实现但不是永久性的。 JDK功能发布中提供了该功能...

    2024-01-30 21:39:07
  • React 知识点整理

    React 知识点整理

    React 知识点整理

    2024-01-30 21:39:00
  • 通俗易懂设计模式解析——抽象工厂模式

    通俗易懂设计模式解析——抽象工厂模式

    前言  前面介绍了单例模式及工厂模式相关知识及示例,今天主要介绍的是抽象工厂模式,上一篇我们讲了工厂模式。将创建对象的任务委托给子类,延迟创建。解决工厂中责任的划分。实现具体工厂与产品之间的一一对应。解决的是”单个对象”的问题。  华为工厂除了生产华为手机之外。肯定也会有原件配套的充电线和耳机。这时工厂对应的是一套产品该如何解决了呢?显然不再适合使用工厂模式了。今天将的抽象工厂模...

    2024-01-30 21:38:25
  • python调用程序call_Python下的subprocess.call()使用和注意事项

    Python虽然有许多优秀的第三方库,但在实际使用的时候免不了使用一些cmd调用的程序,毕竟这类程序比较底层,更快、也更稳定。比如GDAL、FFmpeg、 ImageMagick等。利用Python调...

    2024-01-30 21:38:18
  • 详解TCP/IP协议栈

    详解TCP/IP协议栈

    之前对网络各层作用的了解一直都比较模糊,对各个协议的作用也不甚清楚,最近看到了一篇对TCP/IP协议栈讲解比较清晰的博文,特地转载过来。什么是TCP/IP协议栈TCP/IP 协议栈是一系列网络协议的总...

    2024-01-30 21:37:44
  • SpringBoot devtools热部署

    SpringBoot devtools热部署

    一、pom.xml添加依赖二、修改idea默认配置三、测试是否生效一、pom.xml添加依赖&lt;dependencies&gt; &lt;!-- 基础组件--&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId...

    2024-01-30 21:37:38