欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue中elementUI使用checkbox勾选并动态添加模块框

程序员文章站 2022-05-10 19:48:26
...

elementUI使用checkbox勾选并动态添加模块框

这两天在做公司的一个项目时,制作了一个不错的小功能,使用的框架是elementUI,通过checkbox勾选需要的模块,动态添加模块框的一个功能效果。虽然难度不大,但还是踩了一些坑,在这记录并给需要此功能的开发者一些帮助。先上图:

效果预览

vue中elementUI使用checkbox勾选并动态添加模块框
vue中elementUI使用checkbox勾选并动态添加模块框
vue中elementUI使用checkbox勾选并动态添加模块框
下面就开始制作吧~
elementUI的引入就不必多说了,详细见官网

创建模块框和按钮组件

首先,现在页面完成三个模块框和一个添加按钮(因为我各个组件都组件化,便于维护和美观),下面的添加按钮的组件模块,这个坑踩的很深沉,由于我没有认真仔细细心的看elementUI的文档(该打),导致大大拖慢了我的速度,卡在此处良久,先听我把坑娓娓道来,再赏代码不迟:

  1. 在el-checkbox-group中的v-model绑定的值modules,是将checkbox选中项的label丢到modules这个数组中,所以要判断是否选中,需查看modules中的是否有对应的值;(年少的我,妄想在checkbox后面加上原生checked改变它是否选中的状态,真的太年轻了~~~~但是重点来了,因为我的这种妄想,让我又看到一个众人踩过的坑位,如下);
  2. 在created或者mounted中,想要通过ref获取 $ refs对应的DOM元素,但结果总是 undefined,为什么呢?因为那时候通过父级或者请求数据后,该DOM元素还未创建挂载完成,所以需要使用this.$nextTick ,或者setTimeout中执行;
  3. el-checkbox-group中的v-model绑定的值modules,是一个数组;
// 添加模块 按钮组件
<template>
  <div class="add-module">
    <el-button type="primary" round @click="addNewModules()">添加模块</el-button>
     <!-- 点击后的弹出窗 -->
    <el-dialog title="添加模块" :visible.sync="DialogVisible" :append-to-body="true">
      <el-form>
        <el-checkbox-group v-model="modules">
          <el-checkbox label="UsageRate" name="modules">车辆/人员月度使用率</el-checkbox>
          <el-checkbox label="FaultStatistics" name="modules" >故障统计</el-checkbox>
          <el-checkbox label="AttendanceStatistics" name="modules">人员出勤率统计</el-checkbox>
        </el-checkbox-group>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="DialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submit()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  components: {},
  // 父传子 item 用于接收父级的modules状态值
  props: ['item'],
  data () {
    return {
      DialogVisible: false,
      modules: []
    }
  },
  computed: {
  },
  methods: {
    addNewModules () {
      this.DialogVisible = true
      this.updateModules()
    },
    submit () {
	// 提交后 把modules这个数组咦参数的形式传递给父级
      this.$emit('addModules', this.modules)
      this.DialogVisible = false
    },
    updateModules () {
    // 每次点击 添加模块 按钮 
    // 判断一次 当前item(父级的modules中模块是否展示的状态情况)
    // 如果展示 则对应的checkbox也打上勾
      this.modules = []
      if (this.item.faultShow) {
        this.modules.push('FaultStatistics')
      }
      if (this.item.usageShow) {
        this.modules.push('UsageRate')
      }
      if (this.item.attendanceShow) {
        this.modules.push('AttendanceStatistics')
      }
    }
  }
}
</script>

首页内容

下面的是首页的信息,其他三个模块,我就不放完整代码,随意创建,内容自拟;到此首页渲染中,有面临另一个问题,那便是怎么根据checkbox勾选中的提交,展示对应需要展示的模块框呢?来来来~~ Let me tell u

  1. 在子组件中,已经使用 this.$emit的方法将数组 modules传到父组件,方法名为addModules,而这时,判断modules这个数组有哪些模块label的值,有则将其组件的展示的值改为 true,否则为 false,这时使用了JSON.stringify的方法判断;
  2. 解决其一,但在上一项说的判断中,如果不断使用if(){}else{}来判断是否存在该值,只会是你的代码丑陋不堪,当然switch…case也稍好一些;这里使用了之前一位老师教导的享元模式,其原理为提取出其中的不同点作为享元,减少代码的重复性,使其美观程度上升,并且拓展性也强。
// html
// 首页
// 添加模块 按钮组件 
// item 为父传子的通道
<AddModule @addModules="add($event)" :item="getModules"/>
// 下面三个为模块框组件 名字自拟
<UsageRate v-if="modules.usageShow" @closeUsage="modules.usageShow = false"/>
<AttendanceStatistics v-if="modules.attendanceShow" @closeAttendance="modules.attendanceShow = false"/>
<FaultStatistics v-if="modules.faultShow" @closeFault="modules.faultShow = false"/>
<script>
export default {
  data () {
    return {
      modules: {
        usageShow: true,
        faultShow: true,
        attendanceShow: true
      }
    }
  },
  // 设置计算属性 根据依赖属性 实时返回最新的modules值
  computed: {
    getModules: function () {
      return this.modules
    }
  },
  methods: {
    judgeShow (name, moduleName, moduleShow) {
      if (JSON.stringify(name).indexOf(moduleName) === -1) {
        this.modules[moduleShow] = false
      } else {
        this.modules[moduleShow] = true
      }
    },
    add (name) {
      // 享元模式
      var modulesName = [['FaultStatistics', 'faultShow'], ['UsageRate', 'usageShow'], ['AttendanceStatistics', 'attendanceShow']]
      if (name.length) {
        modulesName.forEach(item => {
          this.judgeShow(name, item[0], item[1])
        })
      } else {
        this.modules.faultShow = false
        this.modules.usageShow = false
        this.modules.attendanceShow = false
      }
      // 轻提示
      this.$message({
        message: '保存成功',
        type: 'success'
      })
    }
  }
}
</script>

总结

虽然只是一个小小的功能,但是在各种坑下,我还是啃了良久,对此,我认为效率是最重要的,使用正确的方法才是重点,当遇到bug时,缜密分析,多打印出其中的值,便能知道bug所在,并且还有代码的优化,尽量使自己的代码美观优雅,增加其可拓展性和可复用性,这是成为一个优秀的程序员必备的能力。

文章若有什么错误,望大佬们不吝赐教,谢谢~~~

相关标签: elementUI