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

这两天在做公司的一个项目时,制作了一个不错的小功能,使用的框架是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所在,并且还有代码的优化,尽量使自己的代码美观优雅,增加其可拓展性和可复用性,这是成为一个优秀的程序员必备的能力。

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

Logo

前往低代码交流专区

更多推荐