Bootstrap

Vue2使用v-model封装ElementUI_CheckBox组件

核心

可以查阅这篇文章,看一些v-model的具体实现;
简介来讲,就是自定义属性和自定义方法的结合使用。
Vue2.0、Vue3.0分别使用v-model封装组件

首先新建脚手架引入element-ui组件和样式;

新建vCheckBox.vue组件:


<template >
  <div>
    <div class="inputBox" v-if="title">
      <p class="inputBoxP">{{title}}</p>
      <el-checkbox-group class="radiogroup" v-model="checkList" @change="inputFun">
        <el-checkbox v-for="item in options" :key="item.key" :label="item.key">{{item.value}}</el-checkbox>
      </el-checkbox-group>
    </div>
    <el-checkbox-group v-else class="radiogroup" v-model="checkList" @change="inputFun">
      <el-checkbox v-for="item in options" :key="item.key" :label="item.key">{{item.value}}</el-checkbox>
    </el-checkbox-group>
  </div>
</template>
<script>
export default {
  model: {
    prop: "value",
    event: "inputFun"
  },
  data() {
    return {
      checkList: []
    };
  },
  props: {
    value: {
      type: Array,
      require: false,
      default: () => []
    },
    title: {
      type: String,
      require: false
      // default: "请传入Titlt"
    },
    placeholder: {
      type: String,
      require: false,
      default: "请选择"
    },
    options: {
      type: Array,
      require: true,
      default: []
    }
  },
  watch: {
    value: {
      handler(newVal, oldVal) {
        if (newVal) {
          this.checkList = newVal;
        }
      },
      immediate: true
    }
  },
  methods: {
    inputFun(e) {
    //不改变地址 可能导致form校验的时候拿不到最新的值
      this.$emit("inputFun", [...this.checkList]);
    }
  }
};
</script>
<style lang="less"  scoped>
.inputBox {
  margin-bottom: 10px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  width: var(--boxWidth);
  .inputBoxP {
    text-align: right;
    white-space: nowrap;
    width: 150px;
  }
  .inputBoxIpt {
    width: 200px;
  }
  .radiogroup {
    width: 200px;
    height: 32px;
    line-height: 32px;
    display: flex;
    align-items: center;
  }
}
</style>
</script>

<style lang="less" scoped>
.inputBox {
  margin-bottom: 10px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  width: var(--boxWidth);
  .inputBoxP {
    text-align: right;
    white-space: nowrap;
    width: 150px;
  }
  .inputBoxIpt {
    width: 200px;
  }
}
</style>

我这里根据有没有传递title属性,做了渲染判断。原因在于这个组件要分别使用在form表单中和单独使用。

单个使用

针对有title的情况
使用肯定需要按部就班:引入_注册_页面使用。

import vCheckBox from "@/components/elementCom/CheckBox";

  components: {
    vCheckBox,
  }

页面使用:

 <v-check-box
      v-model="msg8"
       title="msg8"
       :options="[ {
       key: '3',
       value: '蚵仔煎'
     }, {
       key: '4',
       value: '龙须面'
     }, {
       key: '5',
       value: '北京烤鸭'
     }]"
     />

data:

  data() {
    return {
      msg: "1",
      msg2: "2",
      msg3: "3",
      msg4: "4",
      msg5: "",
      msg6: "1",
      msg7: "2",
      msg8: ["3", "5"],
      startDate: new Date()
    };
  },

结果:
在这里插入图片描述

收集输入的值:

 <el-button type="primary" @click="getAllInputFun">主要按钮</el-button>
 
  methods: {
  getAllInputFun() {
      console.log(this.$data,"data");
    },
  }

![在这里插入图片描述](https://img-blog.csdnimg.cn/53f156509df641e0bcf89b81733fc953.png

表单使用

针对没有title的情况

  <el-form
      :model="ruleForm"
        :rules="rules"
        ref="ruleForm"
        label-width="250px"
        class="demo-ruleForm"
      >
           <el-form-item label="活动性质" prop="type">
            <vCheckBox
              v-model="ruleForm.type"
              :options="[ {
	                 key: '3',
	                  value: '蚵仔煎'
	                  }, {
	                  key: '4',
	                  value: '龙须面'
	                  }, {
	                  key: '5',
	                  value: '北京烤鸭'
	                  }]"
            ></vCheckBox>
          </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
  </el-form>
          

data:

 data() {
    let validatePass2 = (rule, value, callback) => {
      console.log(rule, "rule, value,");
      console.log(!value);
      console.log(value.length === 0);
      this.$nextTick(() => {
        if (!value || value.length === 0) {
          callback(new Error("请选择活动性质"));
        } else {
          callback();
        }
      });
    };
    return {
      ruleForm: {
        type: [],
      },
      rules: {
        type: [
          {
            type: "array",
            required: true,
            validator: validatePass2,
            // message: "请至少选择一个活动性质",
            trigger: "change"
          }
        ],
      }
    };
  },

methods:

  methods: {
    submitForm(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          alert("submit!");
          console.log(this.ruleForm, "ruleForm");
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    }
  }
;