zoukankan      html  css  js  c++  java
  • vue教程:封装了一个checkbox组件

    工作中发现默认vue绑定checkbox很不方便,存在下面几个问题。

    1、如果传递的数值不是数组,那默认绑定值就会转为true或false但是作为后端人员,true或flase这类值一般都是用数值型字段来保存,比如1和0,我们后台传递出来的数据往往就直接是0或1.

    2、如果有多个checkbox,那就需要传递的数值是数组,但是实际中往往一组checkbox提交后台后,就是保存在一个nvarchar字段中,如果需要和前台配合,在读取的时候就需要把字符串转为数组才能实现双向绑定。

    基于以上原因,封装了一个checkbox组件,代码如下,希望对大家有帮助。

    //ui-checkbox组件
    Vue.component("ui-checkbox", {
     props: {
     value: { default: "" },
     dataSource: { default: [] }
     },
     inheritAttrs: false,
     methods: {
     //获取父级的v-model
     getModel: function () {
     if (Array.isArray(this.value)) {
     vModel = this.value;
     }
     else {
     vModel = this.value.toString().split(",");
     }
     return vModel
     },
     //清除冗余数值
     filterModel: function (vModel) {
     var dataSource = this.dataSource;
     var canSetValue = [];
     var dataSourceValue = [];
     for (var i = 0; i < dataSource.length; i++)
     {
     dataSourceValue.push(dataSource[i].value.toString()); //需要转为字符串,兼容数字类型值
     }
     vModel.forEach(function (item, index) {
     var index = dataSourceValue.indexOf(item);
     if (index > -1) {
     canSetValue.push(item);
     }
     });
     return canSetValue;
     },
     onChange: function (event) {
     var vModel = this.getModel(); //每次触发都先获取父级的v-model,保证多个选项的数据同步,v-model初始值中可能存在冗余数据,后面需要用filterModel过滤掉冗余数据。
     if (this.dataSource.length <= 1)
     {
     vModel.splice(0, vModel.length);
     }
     var $obj = event.target;
     var index = vModel.indexOf($obj.value);
     if ($obj.checked){
     if (index < 0)
     {
     vModel.push($obj.value);
     }
     }
     else {
     if (index >= 0) {
     vModel.splice(index, 1); //数组中移除
     }
     }
     vModel = this.filterModel(vModel);//清除冗余数值
     if (!Array.isArray(this.value)) {
     vModel = vModel.join(",");//如果v-model是字符串,同步时候也转为字符串。
     }
     console.log(vModel)
     this.$emit("change",vModel);//同步父级的v-model
     },
     isChecked: function (val)
     {
     var vModel = this.getModel();
     //务必toString()后再查找,否则会和数值型不兼容。
     if (vModel.indexOf(val.toString()) > -1)
     {
     return true;
     }
     else
     {
     return false;
     }
     }
     },
     template: `<span :data-value="value">
     <label class="checkbox-inline" v-for="item in dataSource" :key=item.value> <input type="checkbox" :checked="isChecked(item.value)" v-on:change="onChange($event)" :value="item.value" v-bind="$attrs" /> {{item.label}}</label>
     </span>`
    });
    

    上面代码大家可以下载自己调试,重要地方都加了注释。

    父级页面调用时候v-model直接传递字符串即可,如下:

     var formData = {Love:"写代码"};
     var vue = new Vue({
     el: "#myForm",
     data: formData,
     });
    

    单选的调用方法

    <ui-checkbox v-model="Love" v-on:change="Love=$event" :data-source="[{value:1,label:'是否有爱好'}]"></ui-checkbox>
    

    这样就可以保证选种后Love的值为1,如果不选,值就为空,提交到后台很容易处理。

    效果如下:

    选中后v-mode的值同步改为1,不再是vue默认的true或false。

    如果有多个选项,可以这样调用:

    <ui-checkbox v-model="Love" v-on:change="Love=$event" :data-source="[{value:'read',label:'读书'},{value:'write',label:'写字'}]"></ui-checkbox>
    

    在父级调用的时候,v-model可以传递逗号隔开的字符串,也可以直接传递数组,更具有实用性,单选时候效果如下:

    两个都选中的时候,效果如下:

    调用时候我们初始默认值为:{Love:"写代码"};

    很明显这是一个冗余值,组件中通过 filterModel方法过滤掉了。

    如果你想按vue默认的方式来工作,那么初始默认值可以改为数组形式:

    var formData = {Love:[]};
    

    这样点击触发后传递出来的就是数组,效果如下:

    以上是本人今天工作项目中封装的一个小组件,希望大家喜欢,欢迎转发。

  • 相关阅读:
    linux一些配置
    tomcat启动后,页面无法访问
    利用jmeter实现多IP压测
    java操作数据库
    excle中表头分割单元格
    常用的最大流算法 Dinic 和 最小费用最大流SPFA写法
    [kuangbin]带你飞之'网络流'专题
    (留坑以后再看)一般图'最大匹配' 带花树 算法
    二分图'多重匹配'
    二分图'最大匹配' HK 算法
  • 原文地址:https://www.cnblogs.com/huaguo/p/11635892.html
Copyright © 2011-2022 走看看