美文网首页
Vue 增删改查

Vue 增删改查

作者: 乖小猪猪 | 来源:发表于2022-08-23 10:03 被阅读0次

    此demo选用的vue2.x版本
    看完你将收获以下几点技能:

    1. 快速创建vue项目
    2. 理解vue常用指令的使用场景
    3. 网站快速成型工具Element-ui使用
    4. 项目中增删改查的具体应用

    效果图

    image.png

    技术栈

    vue2.x + Element-ui + sass + esLint + standard

    构建工具选择

    如你遇到包下载慢、依赖不同导致各种bug等等(因为npm镜像地址在国外所以访问会慢有的时候还访问不到),可选用淘宝镜像地址(淘宝镜像同步频率目前为10分钟一次以保证尽量与官方服务同步)或者pnpm
    pnpm是高性能的npm,pnpm节省磁盘空间,安装速度快;通过内容可寻址存储(CAS)、符号链接(Symbolic Link)、硬链接(Hard Link)等管理依赖包。

    设置淘宝镜像地址

    // 淘宝镜像新地址旧地址
    https://registry.npm.taobao.org // 旧
    https://registry.npmmirror.com  // 新
    // 永久使用
    npm config set registry https://registry.npmmirror.com
    // 使用淘宝镜像并把npm设置为cnpm
    npm install -g cnpm --registry=https://registry.npm.npmmirror.org
    // 查看是否设置成功
    npm get registry 
    

    换回npm官网地址

    如果淘宝镜像影响你发布模块可这样换回去

    npm config set registry https://registry.npmjs.org
    

    安装pnpm

    npm install -g pnpm
    // 或
    cnpm install -g pnpm
    

    一.安装vue

    在安装之前先确保安装了node环境, 如果没有安装,去官网最新稳定版下载nodejs

    全局安装vue-cli

    一键生成工程化的vue项目

    cnpm install -g @vue/cli
    # 或者
    yarn global add @vue/cli
    

    查看vue-cli版本

    vue  -V  // @vue/cli 5.0.8 vue-^2.6.14
    

    创建vue项目

    vue create vue2-demo
    // 或者
     mkdir vue2-demo && cd vue2-demo // 创建vue2-demo文件夹并进入目录
    vue create .  // 在当前创建vue项目
    

    接下来会出现选择以前的配置项还是vue默认创建的项目,还是手动选择,
    选择Manually select features(手动安装),会进入下一步操作

    用空格和上下箭头选择配置项

    CSS Pre-processors  // CSS 预处理器
    Linter / Formatter  // 代码风格检查和格式化(选择保存和提交时校验)
    选择standard编码规范
    Sass/SCSS (with dart-sass)  // 如果不想安装node-sass选择dart-sass
    

    查看standardjs编码规范

    二.安装Element-ui

    cnpm i element-ui -S
    

    三.使用element-ui布局页面

    第一步先在main.js 引入ui

    完整引入

    import Vue from 'vue';
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    import App from './App.vue';
    
    Vue.use(ElementUI);
    
    new Vue({
      el: '#app',
      render: h => h(App)
    });
    

    两种引入方式: 完整引入和按需引入,建议选用按需引入,具体操作见官网
    流程:官网-> 组件 -> 快速上手
    element官网

    第二步:布局页面

    找到Container 布局容器模块,选择第一个模版 由header和main组成的模块,也就是分为标题和主内容部分

    <el-container>
      <el-header>Header</el-header>
      <el-main>Main</el-main>
    </el-container>
    

    按模块添加如下代码:

    <el-container>
        <el-header>vue2.x增删改查part01</el-header>
        <el-container>
          <el-main>
            <el-form :inline="true" :model="formInline" class="demo-form-inline">
              <el-form-item>
                <el-input placeholder="请输入用户名" v-model="formInline.username" clearable>
              </el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" icon="el-icon-search">查询</el-button>
                <el-button type="success" @click="show">添加</el-button>
                <el-button type="danger">批量删除</el-button>
              </el-form-item>
            </el-form>
            <el-table v-if="tableData.length > 0" :data="tableData" border style="width: 100%">
              <el-table-column type="selection" width="40">
              </el-table-column>
              <el-table-column fixed prop="date" label="日期" width="150">
              </el-table-column>
              <el-table-column prop="name" label="姓名" width="120">
              </el-table-column>
              <el-table-column prop="province" label="省份" width="120">
              </el-table-column>
              <el-table-column prop="city" label="市区" width="120">
              </el-table-column>
              <el-table-column prop="address" label="地址" width="300">
              </el-table-column>
              <el-table-column prop="zip" label="邮编" width="120">
              </el-table-column>
              <el-table-column fixed="right" label="操作">
                <template slot-scope="scope">
                  <el-button
                    @click="handleClick(scope.row)"
                    type="primary"
                    size="mini"
                    >查看</el-button
                  >
                  <el-button type="success" size="mini">编辑</el-button>
                  <el-button type="danger" size="mini">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
            <div class="nodata" v-else>无数据...</div>
          </el-main>
        </el-container>
      </el-container>
    

    弹出框模版代码

    <!-- dialog start -->
        <el-dialog
          title="默认弹层标题"
          :visible.sync="showDialog"
          custom-class="mydialog"
        @close="close"
        >
          <div slot="title" align="left">添加信息</div>
          <el-form
            :model="addQuery"
            :inline="true"
            label-position="right"
            label-width="80px"
          >
            <el-form-item label="用户名">
              <el-input v-model="addQuery.username" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="选择日期">
              <el-date-picker
                v-model="addQuery.date"
                type="date"
                style="width:90%"
                placeholder="选择日期"
              >
              </el-date-picker>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="close">取 消</el-button>
            <el-button type="primary" @click="add">确 定</el-button>
          </div>
        </el-dialog>
        <!-- dialog end! -->
    

    页面js初始数据

    data () {
        return {
          idx: 1, // 初始化id 为了使用本地数据 
          editId: 0, // 要编辑的id
          showDialog: false, // 弹出层开关
          addQuery: { // 添加字段
            username: '',
            date: ''
          },
          formInline: { // 查询字段
            username: ''
          },
          tableData: [
            {
              id: 1,
              date: '2016-05-02',
              name: '王小虎1',
              province: '上海',
              city: '普陀区',
              address: '上海市普陀区金沙江路 1518 弄',
              zip: 200333
            },
            {
              id: 2,
              date: '2016-05-04',
              name: '王小虎2',
              province: '上海',
              city: '普陀区',
              address: '上海市普陀区金沙江路 1517 弄',
              zip: 200333
            },
            {
              id: 3,
              date: '2016-05-01',
              name: '王小虎3',
              province: '上海',
              city: '普陀区',
              address: '上海市普陀区金沙江路 1519 弄',
              zip: 200333
            },
            {
              id: 4,
              date: '2016-05-03',
              name: '王小虎4',
              province: '上海',
              city: '普陀区',
              address: '上海市普陀区金沙江路 1516 弄',
              zip: 200333
            }
          ]
        }
      },
    methods: {
        handleClick (row) {
          console.log(row) // 查看 暂时不做什么功能
        }
    }
    

    备注:如果table出不来,一片空白,原因是element-ui版本过高,在package里修改版本后 element-ui版本,cnpm install即可

    四.添加-增/删/改/查 逻辑

    查询

    <el-input placeholder="请输入用户名" v-model.trim="formInline.username" clearable></el-input>
    <el-button type="primary" icon="el-icon-search" @click="search">查询</el-button>
    // js-code
    search () {
         /*
         第一步:先拿到input输入的内容
         第二步: 遍历数组找到元素filter
         第三步:原数组赋值-更新视图
          */
         const userName = this.formInline.username
         if (userName === '') {
           alert('请输入查询内容哦') // 暂时用alert 哦~,可以用element自带的漂亮框
           return
         }
         const tableData = JSON.parse(localStorage.getItem('tableData'))
         this.tableData = tableData.filter(item => item.name === userName)
    }
    

    注意:因为是本地数据,当查询条件有一个成立,不刷新页面的情况,再次查询会出现无数据,原因是:
    假如:第一次查询name为王小虎1,把过滤的结果赋值给tableData,那么,
    此时tableData里就只有name为王小虎1的这条数据;
    再次查询,即从最新的tableData里查询,查询name为王小虎2的,显
    然找不到,所以也就会出现无数据情况。
    解决办法:因为是本地数据库,那么我们可以在页面挂载成功后,把tableData放到本地缓存一份,增加或者删除的时候更新本地缓存,查询的时候从本地缓存里查询,即可解决这个问题。

    新增localStoreSetItem函数

    localStoreSetItem () {
          localStorage.setItem('tableData', JSON.stringify(this.tableData))
        }
    mounted () {
        this.idx = this.tableData.length // 本地数据生成id,用接口方式不需要这行代码哦
        this.localStoreSetItem()
      },
    

    添加逻辑

    <el-button type="primary" @click="add">确 定</el-button>
    add () {
          /*
          第一步:拿到弹出层输入框内容
                定义日期格式化函数:formatDate 转换格式
          第二步:追加到tableData数组中
                定义插入对象格式
          第三步:给tableData赋值 ->更新视图
          第四步:弹出层数据数据恢复默认,关闭弹出层后把属性设置为空 新增close
          */
          const { username, date } = this.addQuery
          const newDate = this.formatDate(date)
          const obj = {
            date: newDate,
            name: username,
            province: '上海',
            city: '普陀区',
            address: '上海市普陀区金沙江路 1518 弄',
            zip: 200333
          }
          this.tableData.unshift(obj)
          this.showDialog = false
        },
        close () {
          this.showDialog = false
          this.addQuery.name = ''
          this.addQuery.date = ''
        },
      }
    
    

    删除逻辑

    // 模版
    <el-button type="danger" size="mini" @click="del(scope.row.id)">删除</el-button>
    
    // js
    del (id) {
          // 两种方法:filter,和splice 推荐splice
          // this.tableData = this.tableData.filter((e) => e.id !== id)
          // 先查找当前要删除的id在数组的位置
          const index = this.tableData.findIndex((item) => item.id === id)
          // 从当前位置开始删除1条内容
          this.tableData.splice(index, 1)
          // 更新缓存中的tableData数据
          this.localStoreSetItem()
        }
    

    注意:删除的两种方法;注意更新本地缓存数据,不然有bug哦,删除后的元素还能被搜索到哦

    批量删除

    需要在el-table组件上绑定事件函数,@selection-change=“自定义函数”,可以拿到选中的元素集合数组展示

    // 模版
    <el-table
              v-if="tableData.length > 0"
              @selection-change="handleSelectionTable"
              :data="tableData"
              border
              style="width: 100%"
            >
    // js
    handleSelectionTable (val) {
          this.selectionTableArr = val
        },
    delMore () {
          /* 一.如果是后台接口只需要传递[id1,id],那我们直接把选中的id拿出来即可
          两种方法:forEach,reduce
          */
          console.time('forEach')
          const ids = []
          this.selectionTableArr.forEach(item => {
            ids.push(item.id)
          })
          console.timeEnd('forEach') // forEach: 0.02099609375 ms
          // reduce效率最高
          console.time('reduce')
          const ids1 = this.selectionTableArr.reduce((arr, item) => {
            arr.push(item.id)
            return arr
          }, [])
          console.timeEnd('reduce') // reduce: 0.009033203125 ms
          console.log(ids1)
          /* 二. 以上是给接口的,那么现在处理本地的批量删除
            第一步:循环删除 -> 递归 do-while; 递归条件已选择的数组len小于0的时候停止
            第二步:需要递归处理的事情,也就是while放的代码:先查找已选中的id在原数组的位置,然后splice删除1项
            第三步:更新本地缓存
          */
          let len = this.selectionTableArr.length
          do {
            const index = this.tableData.findIndex(item => item.id === this.selectionTableArr[len - 1].id)
            this.tableData.splice(index, 1)
            len--
           // 刚更新本地缓存
            this.localStoreSetItem()
          } while (len > 0)
        },
    

    修改逻辑

    因为修改逻辑处理完数据回填后,走的还是添加的逻辑,所以添加代码修改为

     show () {
          this.showDialog = true
          this.editId = 0
        },
    edit (row) {
          /*
            分析:把当前要编辑的row拿到;然后赋值给弹出层表单model的addQuery对象,addQuery对象更新input的v-model值更新
            第一步:拿到当前点击的row对象
            第二步:给addQuery对象的属性赋值 for in 或者 深拷贝
            第三步:点击保存后:1.如果是走的接口,那么会和添加是一样的逻辑
                             2.如果更新本地缓存,那么先找到当前id所在数组的位置
                               接着,用splice(index, 1, 新的内容对象) // 删除一条用新的内容替换
            第四步:更新最新缓存数据tableData
    
          */
          this.showDialog = true
          for (const k in row) {
            this.addQuery[k] = row[k]
          }
          this.editId = row.id
          this.showDialog = true
     },
    add (id) {
          /*
          第一步:拿到弹出层输入框内容
                定义日期格式化函数:formatDate 转换格式
          第二步:追加到tableData数组中
                定义插入对象格式
          第三步:给tableData赋值  更新视图
          第四步:弹出层数据数据恢复默认,关闭弹出层,
          */
          !this.showDialog && (this.showDialog = true)
          const {  name, date } = this.addQuery
          if (name === '' && this.date === '') {
            alert('请填写内容')
            return
          }
          // 如果有要修改的数据,把之前的旧数据删除
          const index = this.tableData.findIndex(item => id === item.id)
          const newDate = this.formatDate(date)
          const obj = {
            id: ++this.idx,
            date: newDate,
            name,
            province: '上海',
            city: '普陀区',
            address: '上海市普陀区金沙江路 1518 弄',
            zip: 200333
          }
         if (this.editId > 0) {
            this.tableData.splice(index, 1, obj) // 如果是修改元素顺序不变
            this.editId = 0
          } else {
            this.tableData.unshift(obj) // 如果是新添加第一条出现最上面
          }
          this.localStoreSetItem() // 不管是添加还是修改都要更新本地缓存
          this.close()
        },
    

    五. 总结

    1.添加或者修改数据后再次打开弹出层记得清空上一次的记录状态
    2.使用本地数据和真实项目中的接口操作数据有很多地方变化,一定要注意之间的关系。

    相关文章

      网友评论

          本文标题:Vue 增删改查

          本文链接:https://www.haomeiwen.com/subject/qbgugrtx.html