最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Element-ui checkbox

    正文概述 掘金(努力的阿布水晰_)   2021-04-24   583

    Element-ui checkbox

    Element-ui checkbox

    <template>
      <!-- `checked` 为 true 或 false -->
      <el-checkbox v-model="checked">备选项</el-checkbox>
    </template>
    <script>
      export default {
        data() {
          return {
            checked: true
          };
        }
      };
    </script>
    

    剖析

    • checkbox 有三种状态:选中,取消选中,半选
    • checkbox 有三种使用情况:
    • 单独使用, v-model绑定的值为布尔类型
    • 单独使用,v-model绑定的值为数组类型,且需与label搭配
    • 与checkbox-group搭配使用,且需与label搭配(checkbox-group见下回)

    测试代码

    <template>
      <div>
        <p>checkbox</p>
        <!-- 第一种情况 -->
        <y-checkbox v-model="checkboxValue" @change="handleChange">杭州</y-checkbox>
        <!-- 第二种情况 -->
        <y-checkbox v-model="checkboxArr" label="1" @change="handleChange">杭州</y-checkbox>
        <!-- 半选中状态 -->
        <y-checkbox 
          :indeterminate="checkboxIndeterminate" 
          v-model="checkboxIndeterminateValue"
          @change="handleIndeterminate">半选中状态</y-checkbox>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          checkboxValue: true,
          checkboxArr: [
            '1',
            '2',
            '3',
          ],
          checkboxIndeterminate: true,
          checkboxIndeterminateValue: false,
        }
      },
      watch: {
        checkboxValue() {
          console.log('父组件checkboxValue', this.checkboxValue)
        }
      },
      methods: {
        handleChange(data) {
          console.log('父组件change事件', data);
        },
        handleIndeterminate(data) {
          console.log('半选', data);
          // 将半选控制标识更改为false, 便可以正常选中和取消选中了
          this.checkboxIndeterminate = false;
        }
      }
    }
    </script>
    
    • 注意:单独使用checkbox时,且设置了半选中:indeterminate="checkboxIndeterminate" ,则需要绑定change事件以更改该checkboxIndeterminate为false,从而正常选中和取消选中

    组件checkbox

    template
    <template>
        <!-- checkbox选中状态: 选中, 不选中, 半选
            单独使用checkbox,如何判断选中状态呢?
            prop接收的value值类型需为布尔类型: true选中, false不选中
            半选中状态如何处理?
            半选中状态下,如果再次点击,将indeterminate置为false, 便可以选中和取消选中了
            但是只能在父组件中控制indeterminate的值(因为子组件不能更改父组件prop传进来的值) -->
        <label
            class="y-checkbox"
            role="checkbox">
            <!-- checkbox分两部分, 一部分是多选框,一部分是标签 -->
            <span 
                class="y-checkbox__input"
                :class="{
                    'is-checked': isChecked,
                    'is-indeterminate': indeterminate,
                }"
                >
                <!-- y-checkbox__inner 替换了原生多选框的样式,原生多选框只有两种状态,通过自定义的样式可定义第三种半选状态-->
                <span class="y-checkbox__inner"></span>
                <!-- 原生多选框, 如果value和labl都没有传, 则选中状态变化后, model值为true或false 
                    定义ref以便获取该dom元素从而通知该原生多选框的选中状态
                    自定义属性 aria-hidden 可直观明白该html是否展示
                -->
                <input
                    ref="checkbox"
                    class="y-checkbox__original"
                    type="checkbox"
                    :value="label"
                    aria-hidden="false"
                    v-model="model"
                    @change="handleChange"/>    
            </span>
            <!-- 标签, 如果子元素存在则展示子元素, 否则标签为label -->
            <span 
                class="y-checkbox__label">
                <slot></slot>
                <templat v-if="!$slots.default">{{label}}</templat>
            </span>
        </label>
    </template>
    

    scripts

    checkbox 选中状态判定

    <script>
    export default {
        name: 'YCheckbox',
        props: {
            value: {},
            // label选中状态的值, 只有在checkbox-group或者value为数组类型的时候方可有效
            label: {},
            // 半选中状态
            indeterminate: Boolean,
        },
        computed: {
            // 原生多选框值的选中状态
            model: {
                get() {
                    return this.value;
                },
                set(val) {
                    console.log('model发生了变化', val);
                    /**
                     * 通知父组件value值发生了变化
                     * v-model双向绑定, 手动通知父组件吗?这是因为并非是value值发生了变化,
                     * 而是另一个依赖变量model发生了变化, model发生变化后value也要变, 所以需要手动触发
                     */
                    this.$emit('input', val);
                }
            },
            /**
             * 选中状态的判定
             * 如何判定选中状态?
             * 这里分三种情况,一种是单个使用(value为布尔类型, label为undefined)
             * 一种情况是单个使用(value为数组类型, label为数组中的某一项)
             * 一种情况是父组件为checkbox-group(value为undefined, label有值)
             */
            isChecked() {
                // this.model.toString(), {}.toString.call(this.model)有什么区别?
                // 若this.model=true, 则 this.model.toString()->true, {}.toString.call(this.model)->[object Boolean]
                console.log('第一种情况', {}.toString.call(this.model), {}.toString.call(this.model) === '[object Boolean]')
                
                // 如果是第一种情况, 单独使用多选框且value值为布尔类型
                if({}.toString.call(this.model) === '[object Boolean]') {
                    return this.model;
                }
                // 如果是第二种情况,单独使用且value为数组类型
                // 数组的判定类型有几种?
                // console.log('第二种情况', this.model, Array.isArray(this.model), this.model.indexOf(this.label), this.model.includes(this.label));
                else if(Array.isArray(this.model)) {
                    console.log(this.model, this.label);
                    // 判断值是否存在于数组中
                    // indexOf和includes的区别
                    return this.model.indexOf(this.label) > -1;
                }
                // 第三种情况,父组件是checkbox-group
                console.log('第三种情况,父组件是checkbox-group');
            }
        },
        methods: {
            /**
             * 父组件可能有change事件,即选中状态变化后的回调
             * 因为这是由原生多选框选中状态变化后的回调,需要等视图更新后方可获取到新值,并将新值传给回调函数
             */
            handleChange() {
                // console.log('原生checkbox发生了变化', this.model);
                this.$nextTick(()=>{
                    this.$emit('change', this.model);
                })
            },
        },
        mounted() {
            console.log('checkbox', this.value, this.label);
            // console.log(this.model.toString(), {}.toString.call(this.model), {}.toString.call(this.model) === '[object Boolean]')
        },
        watch: {
            isChecked() {
                console.log('watchisChecked', this.isChecked)
            }
        }
    }
    </script>
    
    • this.model.toString(){}.toString.call(this.model)的区别
    • indexOfincludes 的区别

    style

    .y-checkbox {
        position: relative;
        margin-right: 30px;
    }
    .y-checkbox:last-child {
        margin-right: 0;
    }
    .y-checkbox__input {
        position: relative;
    }
    .y-checkbox__inner {
        display: inline-block;
        position: relative;
        width: 14px;
        height: 14px;
        border: 1px solid #dcdfe6;
        border-radius: 2px;
        box-sizing: border-box;
        vertical-align: middle;
    }
    .y-checkbox__inner::after {
        content: '';
        display: content-box;
        width: 3px;
        height: 7px;
        position: absolute;
        top: 2px;
        left: 4px;
        box-sizing: border-box;
        border: 1px solid #fff;
        border-top: 0;
        border-left: 0;
        transform: rotate(0deg) scale(0);
    }
    /* 选中样式 */
    .y-checkbox__input.is-checked .y-checkbox__inner {
        background-color: #409eff;
        border-color: #409eff;
    }
    /* 选中后中间的对号,通过旋转45度得到 */
    .y-checkbox__input.is-checked .y-checkbox__inner::after {
        transform: rotate(45deg) scale(1);
    }
    /* 半选中状态 */
    .y-checkbox__input.is-indeterminate .y-checkbox__inner {
        background-color: #409eff;
        border-color: #409eff;
    }
    /* 半选中状态 中间的横杠 */
    .y-checkbox__input.is-indeterminate .y-checkbox__inner::after {
        content: none;
    }
    .y-checkbox__input.is-indeterminate .y-checkbox__inner::before {
        content: '';
        display: inline-block;
        height: 2px;
        background-color: #fff;
        position: absolute;
        top: 5px;
        right: 0;
        left: 0;
        transform: scale(.5);
    }
    /* 隐藏原生多选框 */
    .y-checkbox__original {
        opacity: 0;
        outline: none;
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: -1;
        margin: 0;
    }
    .y-checkbox__label {
        font-size: 14px;
        display: inline-block;
        padding-left: 10px;
    }
    

    总结

    • 该 checkbox 测试,实现v-model、lable属性和change事件
    • checkbox 逻辑跟 radio 有很多相似之处,相似的html结构、判定逻辑
    • checkbox 三种选中状态(注意半选中状态切换到选中状态和取消选中状态)以及其两种使用形式
    • indexOf 与 includes 的区别
    • {}.toString.call(obj) 与 obj.toString() 的区别
    • checkbox 选中状态下中间的对号的生成(伪元素创建,旋转)

    起源地下载网 » Element-ui checkbox

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元