• 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出



    参考视频: VUE项目,VUE项目实战,vue后台管理系统,前端面试,前端面试项目

    案例链接
    【前端】Vue+Element UI案例:通用后台管理系统-导航栏(视频p1-16)https://blog.csdn.net/karshey/article/details/127640658
    【前端】Vue+Element UI案例:通用后台管理系统-Header+导航栏折叠(p17-19)https://blog.csdn.net/karshey/article/details/127652862
    【前端】Vue+Element UI案例:通用后台管理系统-Home组件:卡片、表格(p20-22)https://blog.csdn.net/karshey/article/details/127674643
    【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表准备:axios封装、mock数据模拟实战(p23-25)https://blog.csdn.net/karshey/article/details/127735159
    【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表:折线图、柱状图、饼状图(p27-30)https://blog.csdn.net/karshey/article/details/127737979
    【前端】Vue+Element UI案例:通用后台管理系统-面包屑、tag栏(p31-35)https://blog.csdn.net/karshey/article/details/127756733
    【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出(p36-38)https://blog.csdn.net/karshey/article/details/127787418
    【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改、Pagination分页、搜索框(p39-42)https://blog.csdn.net/karshey/article/details/127777962
    【前端】Vue+Element UI案例:通用后台管理系统-登陆页面Login(p44)https://blog.csdn.net/karshey/article/details/127795302
    【前端】Vue+Element UI案例:通用后台管理系统-登陆页面功能:登录权限跳转、路由守卫、退出(p45-46)https://blog.csdn.net/karshey/article/details/127849502
    【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单、动态添加路由(p47-48)https://blog.csdn.net/karshey/article/details/127865621
    【前端】Vue+Element UI案例:通用后台管理系统-项目总结https://blog.csdn.net/karshey/article/details/127867638

    目标

    总体是这样:

    在这里插入图片描述

    点击新增后:

    在这里插入图片描述

    需求:本篇主要是Form表单的填写和Dialog对话框弹出

    • 点击新增或编辑弹出表单对话框
    • 新增:可以新增用户数据
    • 编辑:可以编辑用户数据
    • Form有填写验证
    • 表单的确定按钮:提交
    • 表单的取消按钮:清空并关闭表单

    代码

    0.页面结构

    在这里插入图片描述

    <template>
      <div class="manage">
        <div class="manage-header">
          
    
          
        div>
        <div class="common-table">
          
    
          
        div>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.新增按钮和弹出表单:结构

    按钮:

    <el-button type="primary">+ 新增el-button>
    
    • 1

    表单Form:
    在这里插入图片描述
    观察对应代码,很明显我们要绑定数据,数据已提供:operateFormLabel.js。

    代码中的data是要绑定的数据,rules是表单验证的规则,methods中的方法很典型,我们一会儿会用到。

    表单的html结构:

    
    <el-form :model="form" :rules="rules">
      
      <el-form-item label="姓名" prop="name">
        <el-input placeholder="请输入姓名" v-model="form.name">el-input>
      el-form-item>
    
      <el-form-item label="年龄" prop="age">
        <el-input placeholder="请输入年龄" v-model="form.age">el-input>
      el-form-item>
    
      <el-form-item label="性别" prop="sex">
        <el-select v-model="form.sex" placeholder="请输入性别">
          <el-option label="" value="1">el-option>
          <el-option label="" value="0">el-option>
        el-select>
      el-form-item>
    
      <el-form-item label="出生日期">
        <el-form-item prop="birth">
          <el-date-picker type="date" placeholder="请选择日期" v-model="form.birth">
          el-date-picker>
        el-form-item>
      el-form-item>
    
      <el-form-item label="地址" prop="addr">
        <el-input placeholder="请输入地址" v-model="form.addr">el-input>
      el-form-item>
    el-form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    js中的data:

    data() {
      return {
        // 表单绑定的数据
        form: {
          name: '',
          age: '',
          sex: '',
          birth: '',
          addr: ''
        },
        // 表单验证规则
        rules: {
    
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.新增按钮和弹出表单:点击新增弹出表单

    表单平时是隐藏的,只有在点击新增和点击编辑时才会弹出。这实际上是一个对话框(Dialog)。我们要把它嵌在Form外面。

    在这里插入图片描述
    html:

    
    <el-dialog title="提示" :visible.sync="dialogVisible">
     
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定el-button>
      div>
    el-dialog>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在data中添加:

    // 表单是否打开
    dialogVisible: false,
    
    • 1
    • 2

    效果:点击后才会弹出表单。
    在这里插入图片描述

    3.表单样式

    让表单域一行两个

    由文档:表单-行内表单:

    设置 inline 属性可以让表单域变为行内的表单域

    代码::inline="true"

    • inline:让表单项并排
    • width:让对话框宽度为上级的一半,这样一行就放得下两个表单项
    • label-width:每个el-form-item的宽度
    • 以上均是对应标签的属性Attribute,可在文档中找到

    代码:

    在这里插入图片描述

    效果:

    在这里插入图片描述

    4.表单验证

    需求:

    • 都必填

    其实可以更完善,比如姓名一定要是字符串(不能数字、特殊字符等)、年龄一定是数字、输入必须在多少字符以内…我们这里不搞这么复杂,把rules大致运用一下即可。

    Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。

    • required: true:一定要填
    • message: '请输入名称':没填的话显示什么
    • trigger: 'blur':触发验证的时机:鼠标没有焦点(光标离开)

    代码:

    rules: {
    name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
    age: [{ required: true, message: '请输入年龄', trigger: 'blur' }],
    sex: [{ required: true, message: '请输入性别', trigger: 'blur' }],
    birth: [{ required: true, message: '请输入日期', trigger: 'blur' }],
    addr: [{ required: true, message: '请输入地址', trigger: 'blur' }],
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码中的规则绑定:

    在这里插入图片描述

    效果:必填的会有红色*,没填且鼠标失去焦点则会有message的提示。

    在这里插入图片描述

    5.表单的提交和取消功能:接口、mock相关准备

    后端会提供对数据增删查改的接口:user.js,放在api文件夹下。提交功能肯定会用到“增”和“改”接口。

    我们的网络请求相关接口:在api/index.js下。

    getUser是get请求,另外三个是post请求,参数不同,详看axios文档。

    // 下面四个:用户管理-后端-网络请求接口
    export const getUser = (params) => {
        return http.get('/user/get', params)
    }
    
    export const createUser = (data) => {
        return http.post('/user/create', data)
    }
    
    export const deleteUser = (data) => {
        return http.post('/user/del', data)
    }
    
    export const updateUser = (data) => {
        return http.post('/user/update', data)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    定义mock拦截:我们的用户数据是用mock模拟的(所以会出现逆天的名字和性别的匹配)

    注意,这里的user是后端提供的接口user.js。且除了getUserList都是post请求。至于为什么要这么定义,详看mock的文档(函数参数)。

    import user from './user'
    
    // 用户管理:增删查改
    Mock.mock('/api/user/get',user.getUserList)
    Mock.mock('/api/user/create','post',user.createUser)
    Mock.mock('/api/user/update','post',user.updateUser)
    Mock.mock('/api/user/del','post',user.deleteUser)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6.表单的提交和取消功能

    提交:

    • 先验证是否满足rules
    • 若满足,则提交
    • 将表单清空
    • 将表单关闭

    取消:

    • 将表单清空
    • 将表单关闭

    至于如何提交和清空,我们看一下表单的文档:正好就是这两个方法!

    在这里插入图片描述
    显然,增删查改之后都会显示列表的数据,所以我们先写一个getList的函数,并在mounted生命周期中调用它,查看一下我们mock生成的数据的结构。

    // 获取列表数据
    getList(){
      getUser().then((data)=>{
        console.log(data);
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    控制台:红框内是要展现在Tabel中的。

    在这里插入图片描述
    在Data中定义一个tableData表示列表数据,把网络请求得到的data赋值给tableData。

    // 获取列表数据
    getList(){
      getUser().then((data)=>{
        this.tabelData=data.data.list      
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    接下来就可以写提交功能:

    // 表单提交
    submit() {
      // 要用箭头函数,若用function会报错,不知道为什么
      this.$refs.form.validate((valid) => {
        // 符合校验
        if (valid) {
          // 提交数据
          createUser(this.form).then(() => {
            this.getList()
          })
          // 清空,关闭
          this.closeDialog()
        }
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    关闭功能:

    // 关闭对话框
    closeDialog() {
      // 先重置
      this.$refs.form.resetFields()
      // 后关闭
      this.dialogVisible = false
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    提供的数据和接口

    1-operateFormLabel.js

    const operateFormLabel = [
        {
            model: 'name',
            label: '姓名',
            type: 'input'
        },
        {
            model: 'age',
            label: '年龄',
            type: 'input'
        },
        {
            model: 'sex',
            label: '性别',
            type: 'select',
            opts: [
                {
                    label: '男',
                    value: 1
                },
                {
                    label: '女',
                    value: 0
                }
            ]
        },
        {
            model: 'birth',
            label: '出生日期',
            type: 'date'
        },
        {
            model: 'addr',
            label: '地址',
            type: 'input'
        }
    ]
    
    export default operateFormLabel
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    5-user.js

    import Mock from 'mockjs'
    
    // get请求从config.url获取参数,post从config.body中获取参数
    function param2Obj (url) {
      const search = url.split('?')[1]
      if (!search) {
        return {}
      }
      return JSON.parse(
        '{"' +
        decodeURIComponent(search)
          .replace(/"/g, '\\"')
          .replace(/&/g, '","')
          .replace(/=/g, '":"') +
        '"}'
      )
    }
    
    let List = []
    const count = 200
    
    for (let i = 0; i < count; i++) {
      List.push(
        Mock.mock({
          id: Mock.Random.guid(),
          name: Mock.Random.cname(),
          addr: Mock.mock('@county(true)'),
          'age|18-60': 1,
          birth: Mock.Random.date(),
          sex: Mock.Random.integer(0, 1)
        })
      )
    }
    
    export default {
      /**
       * 获取列表
       * 要带参数 name, page, limt; name可以不填, page,limit有默认值。
       * @param name, page, limit
       * @return {{code: number, count: number, data: *[]}}
       */
      getUserList: config => {
        const { name, page = 1, limit = 20 } = param2Obj(config.url)
        // console.log('name:' + name, 'page:' + page, '分页大小limit:' + limit)
        const mockList = List.filter(user => {
          if (name && user.name.indexOf(name) === -1 && user.addr.indexOf(name) === -1) return false
          return true
        })
        const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
        return {
          code: 20000,
          count: mockList.length,
          list: pageList
        }
      },
      /**
       * 增加用户
       * @param name, addr, age, birth, sex
       * @return {{code: number, data: {message: string}}}
       */
      createUser: config => {
        const { name, addr, age, birth, sex } = JSON.parse(config.body)
        console.log(JSON.parse(config.body))
        List.unshift({
          id: Mock.Random.guid(),
          name: name,
          addr: addr,
          age: age,
          birth: birth,
          sex: sex
        })
        return {
          code: 20000,
          data: {
            message: '添加成功'
          }
        }
      },
      /**
       * 删除用户
       * @param id
       * @return {*}
       */
      deleteUser: config => {
        const { id } = JSON.parse(config.body)
        if (!id) {
          return {
            code: -999,
            message: '参数不正确'
          }
        } else {
          List = List.filter(u => u.id !== id)
          return {
            code: 20000,
            message: '删除成功'
          }
        }
      },
      /**
       * 批量删除
       * @param config
       * @return {{code: number, data: {message: string}}}
       */
      batchremove: config => {
        let { ids } = param2Obj(config.url)
        ids = ids.split(',')
        List = List.filter(u => !ids.includes(u.id))
        return {
          code: 20000,
          data: {
            message: '批量删除成功'
          }
        }
      },
      /**
       * 修改用户
       * @param id, name, addr, age, birth, sex
       * @return {{code: number, data: {message: string}}}
       */
      updateUser: config => {
        const { id, name, addr, age, birth, sex } = JSON.parse(config.body)
        const sex_num = parseInt(sex)
        List.some(u => {
          if (u.id === id) {
            u.name = name
            u.addr = addr
            u.age = age
            u.birth = birth
            u.sex = sex_num
            return true
          }
        })
        return {
          code: 20000,
          data: {
            message: '编辑成功'
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140

    效果

    点击新增后弹出表单:
    在这里插入图片描述
    提交功能:
    在这里插入图片描述

    总代码

    看下一篇吧,已经写到一起去了:下一篇在这

  • 相关阅读:
    【平衡二叉搜索树】细撕AVL树的插入操作
    跳出以人为中心,从事情发展的角度看问题本质
    【Linux】Linux环境基础开发工具使用—— vim | gcc & g++ | make & makefile | 进度条 | git
    Log4j 2.16.0发布,受Log4j漏洞影响的Apache项目一览
    Linux初级知识大全(一)
    15.0、C语言——指针详解(1)
    深入刨析 mysql 底层索引结构B+树
    Java基础—反射
    Grpc MagicOnion库 之 客户端和服务端 (案例版)
    IDEA自定义代码快捷指令
  • 原文地址:https://blog.csdn.net/karshey/article/details/127787418