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

news2024/11/27 16:29:57

目录

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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/720126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工厂水电能耗监测系统组成

工厂水电能耗监测系统是一种用于监测工厂水电能耗的系统&#xff0c;可以帮助工厂管理者了解水电能耗情况&#xff0c;提高能源利用效率&#xff0c;降低生产成本。本文将从系统组成、功能、优点等方面进行介绍。 一、系统组成 工厂水电能耗监测系统由多个部分组成&#xff0c…

MySQL第一天

文章目录 作业1 简述MySQL体系结构CetenOS 7的MySQLyum在线安装CetenOS 7的MySQL的二进制方式安装 作业1 简述MySQL体系结构 MySQL是由SQL接口、解析器、优化器、缓存、储存引擎组成的&#xff0c;MySQL的最重要的是它的储存引擎架构&#xff0c;这种设计将查询处理及其系统任…

【运维工程师学习】Debian安装

【运维工程师学习】Debian安装 1、界面说明2、选择语言3、等待探测并挂载安装介质完成4、设置主机名称、用户信息5、磁盘分区6、创建分区7、最终分区为8、安装ssh9、查看ssh状态10、查看内存大小11、查询系统磁盘及分区情况12、查看各磁盘及分区剩余13、查看ip地址 选择镜像文件…

新服务器配环境

本章节的大概思路为&#xff1a; 1、远程连接服务器 直接远程连接&#xff0c;前的是你要连接的目录名称&#xff0c;后为服务器公网IP。 ssh xxxxxx.xxx.xxx.xxx 远程连接服务器不同端口 -p后为端口名称 ssh xxxxxx.xxx.xxx.xxx -p xxxx 之后输入密码就行了。 2、创建子用…

c语言修炼之猜数字游戏

前言 小伙伴们&#xff0c;今天来学习猜数字游戏叭&#xff01;废话不多说&#xff0c;让我们一起开始学习叭! 思路&#xff1a; 一打开游戏就出现一个菜单然后可以让我们选择是进入游戏还是退出游戏&#xff01; #include<stdio.h> void menu() {printf("*****…

详解高性能无锁队列的实现

一、无锁队列 1.1 什么是无锁队列 无锁队列&#xff08;Lock-Free Queue&#xff09;是一种并发数据结构&#xff0c;它允许多个线程在没有锁的情况下进行并发操作。 传统的队列通常通过互斥锁来实现线程安全的操作&#xff0c;但互斥锁在高并发情况下可能会造成竞争和性能瓶…

【后端面经-Java】AQS详解

【后端面经-Java】AQS详解 1. AQS是什么&#xff1f;2. AQS核心思想2.1 基本框架2.1.1 资源state2.1.2 CLH双向队列 2.2 AQS模板 3. 源码分析3.1 acquire(int)3.1.1 tryAcquire(int)3.1.2 addWaiter(Node.EXCLUSIVE)3.1.3 acquireQueued(Node node, int arg) 3.2 release(int)3…

校园水电节能管理解决方案

随着社会经济的不断发展&#xff0c;能源问题日益突出&#xff0c;节能减排成为了各级各类学校必须面对的问题。学校的水电能源消耗是其中的一个重要方面&#xff0c;因此&#xff0c;如何对校园水电进行节能管理成为了一个迫切的问题。本文将从以下几个方面介绍校园水电节能管…

在选择自动化测试工具时需要考虑哪些因素?

自动化测试工具是软件开发中不可或缺的一部分&#xff0c;它可以提高测试效率、减少人力成本、提升软件质量&#xff0c;那在选择自动化测试工具时需要考虑哪些因素&#xff1f; 测试需求&#xff1a;首先要明确自动化测试的需求是什么&#xff0c;不同的测试需求对应着不同的工…

电子电气架构相关安全体系介绍

摘要&#xff1a; 随着电子电气架构技术的不断升级&#xff0c;整车越来越多的系统和组件对功能安全产生影响&#xff0c;为此&#xff0c;功能安全也从部分关键系统开发&#xff0c;向整车各系统全面开发拓展。同时&#xff0c;由于域集中式、中央集中式等新架构形态的出现&a…

文档翻译免费怎么做?三分钟告诉你

小乐&#xff1a;嘿&#xff0c;小阳&#xff0c;你知道吗&#xff1f;我最近在学习文档翻译英文&#xff0c;真是太神奇了&#xff01; 小阳&#xff1a;哇&#xff0c;真的吗&#xff1f;那听起来很厉害啊&#xff01;文档翻译英文是怎么做的呢&#xff1f; 小乐&#xff1…

深入解析Java多态进阶学习

目录 1.动态绑定机制 实例A实例B实例C2.多态数组 3.多态数组的高阶用法 4.多态参数 5.多态参数的高阶用法 1.动态绑定机制 java的动态绑定机制非常重要 实例A 我们来看一个实例&#xff1a; 阅读上面的代码&#xff0c;请说明下面的程序将输出什么结果&#xff1a; 程序将会…

机器学习24:《数据准备和特征工程-II》收集数据

构建数据集常用的步骤如下所示&#xff1a; 收集原始数据。识别特征和标签来源。选择抽样策略。拆分数据。 这些步骤在很大程度上取决于你如何构建 ML 问题。本文主要介绍——数据收集-Collecting Data。 目录 1. 数据集的大小和质量 1.1 数据集的大小 1.2 数据集的质量 …

.NET Core webapi 从零开始在IIS上面发布后端接口

文章目录 原因环境配置windows环境.NET Core安装开发端安装服务端安装 新建ASP.NET项目 原因 .NET core是以后.NET未来的趋势&#xff0c;虽然我感觉Java在web后端的主导地位10年内不会动摇&#xff0c;因为Java占据了先发优势。 不过C#的特点就是&#xff0c;简单&#xff0…

mysql三大日志之我对Binlog的理解

mysql 我们先来看一下MySQL的基本架构&#xff0c;从大的方面来讲&#xff0c;一个server层&#xff0c;一个引擎层。server层就像一个接口&#xff0c;可以对接任何符合规定的引擎。具体的细节可以参考我之前写过的文章mysql的这些坑你踩过吗&#xff1f;快来看看怎么优化mys…

Blazor 自定义可重用基础组件之 带标头排序的Table

实现点击标头按所在列值进行排序&#xff0c;是一个非常有用的功能&#xff0c;其他的UI一般搞得非常复杂&#xff0c;添加标志图标什么的&#xff0c;使得本就不宽裕的表格更加拥挤。我的思路是&#xff0c;点击所在列的标头部位&#xff0c;传递标头值&#xff0c;然后根据标…

裸机搭建k8s报错记录

安装教程参考 修复一、 cd /etc/kubernetes/manifests vim kube-scheduler.yaml注释掉 重启 systemctl restart kubelet.service问题二、 https://github.com/kubernetes/kubernetes/issues/70202 一直处于创建中状态 网络原因 cat << EOF > /run/flannel/subnet.…

golang 结构体struct转map实践

1、反射 type sign struct { Name string json:"name,omitempty" Age int json:"age,omitempty" } var s sign s.Name "csdn" s.Age 18 //方式1 反射 var data make(map[string]interface{}) t : reflect.TypeOf(s) v : …

第五步:STM32F4端口复用

什么是端口复用&#xff1f; STM32有很多的内置外设&#xff0c;这些外设的外部引脚都是与GPIO复用的。也就是说&#xff0c;一个GPIO如果可以复用为内置外设的功能引脚&#xff0c;那么当这个GPIO作为内置外设使用的时候&#xff0c;就叫做复用。 例如串口 1 的发送接收引脚…

【C++11】移动语义,完美转发

1.移动语义 1.为什么要有移动语义&#xff1f; C中有拷贝构造函数和拷贝复制运算符&#xff0c;但是这需要占用一定的空间 class MyClass { public:MyClass(const std::string& s): str{ s }{};MyClass(const MyClass& m){strm.str;}private:std::string str; };int …