LayUI表单如何下使用Vue?看这里!

背景:因为使用LayUI,select,radio,checkbox 都会被托管,无法双向绑定,所以把这三个 利用layui的样式,用vue重写一遍。

  1. Component 知识 https://cn.vuejs.org/v2/guide/components.html 必须看完才能往下走

  2. 要观察layui托管组件后,生成的Html代码,把对应的html代码拷贝下来。

  3. html代码

    	<div class="layui-form-item">
        <label class="layui-form-label" style="text-align:left;">
            select:
        </label>
        <div class="layui-input-inline">
             <tl-select :list="list3" v-model="targetValue" ></tl-select>
        </div>
        显示的值:{{targetValue}}
    </div>
    
  4. js代码

    Vue.component("tl-select", {
        /*
           !此处数据类型必须是一个函数形式,不能直接写对象。
            每个组件都是相互独立的,如果它们共用一个对象,在更改一个组件数据的时候,会影响到其它
            组件,如果是函数的话,每个组件就都有自己的独立数据,相互之间不会影响。
        */
        props: ["list","value","title","width"],
        data: function() {
            return {
                selectShow: false,
                val: 0,
                showTitle: this.title || '',
                showValue: ''
            };
        },
        template:`<div :class="[selectShow ? 'layui-unselect layui-form-select layui-form-selected' : 'layui-unselect layui-form-select'] " v-clickOut="outsideDirec" :style="{'width':width ? width:''}">
                            <div class="layui-select-title" @click="selectShow = !selectShow">
                                <input type="text" placeholder="" :value="showValue" readonly="" class="layui-input layui-unselect">
                                <i class="layui-edge"></i>
                            </div>
                             <dl class="layui-anim layui-anim-upbit" style="" v-show="selectShow">
                                <dd :class="item.value == value ? 'layui-this':''" v-for="item in list" @click.stop="choose(item)">{{item.key}}</dd>
                            </dl>
                       </div>`,
        methods: {
            choose(value) {
                this.val = value;  //将选中的值赋给指定的input
                this.selectShow = false;  //隐藏下拉框
                this.$emit("input", this.val.value);
                this.showValue = this.val.key;
                this.$emit("change");
            },
            outsideDirec() {
                this.selectShow = false
            },
            test() {
                this.selectShow = false
            },
        },
        mounted() {
            let that = this;
            if(that.value){
                this.list.forEach(item=>{
                    if(item.value == that.value){
                        that.showValue = item.key;
                    }
                })
            }else{
                let tryNum = 0;
                while(tryNum < 3 && !that.value){
                    setTimeout(()=>{
                        this.list.forEach(item=>{
                            if(item.value == that.value){
                                that.showValue = item.key;
                            }
                        })
                    },150);
                    tryNum++;
                }
            }
        },
        directives: {
            clickOut: {
                bind: function(el, binding) {
                    function handler(e) {
                        if (el.contains(e.target)) return false
                        if (binding.expression) {
                            binding.value()
                        }
                    }
                    el.handler = handler
                    document.addEventListener('click', el.handler)
                },
                unbind: function(el) {
                    document.removeEventListener('click', el.handler)
                }
            }
        }
    });
    
  5. 实现完难的select,我们就参考上面 制作checkBox和radio组件吧

    checkBox

    Vue.component("tl-checkbox", {
        props: {
            label:[String,Number,Boolean],
            title:[String],
            value:[Number,String,Array,Boolean],
            disable:[Boolean]
        },
        data: function() {
            return {
                originValue : this.value,
                disabled:this.disable || false
            };
        },
        template:`<div :class="[value.indexOf(label) == -1 ? 'layui-unselect layui-form-checkbox':'layui-unselect layui-form-checkbox layui-form-checked',disabled?'layui-checkbox-disbaled layui-disabled':'']" lay-skin="primary" v-if="value instanceof Array">
                           <span>{{ title }}</span>
                           <i class="layui-icon layui-icon-ok" @click.stop="changeValueHandle(label)"></i>
                      </div>
                    <div :class="value ? 'layui-unselect layui-form-checkbox layui-form-checked':'layui-unselect layui-form-checkbox'" lay-skin="primary" v-else>
                           <span>{{ title }}</span>
                           <i class="layui-icon layui-icon-ok" @click.stop="changeValueHandle()"></i>
                      </div>`,
        methods: {
            changeValueHandle(value) {
                if(!this.disabled){
                    if(this.value instanceof  Array){
                        let index = this.value.indexOf(value);
                        let originValue = this.value;
                        if(index == -1){
                            originValue.push(value);
                        }else{
                            originValue.splice(index,1);
                        }
                        this.$emit("input", originValue);
                    }else{
                        console.log(this.value);
                        this.$emit("input", !this.value);
                    }
                    this.$emit("click");
                }
            },
            changeDisable(bool){
                this.disabled = bool;
            },
            reSetValue(value){
                this.originValue = value;
            },
        }
    });
    

    radio

    Vue.component("tl-radio", {
        props: {
            label: [String,Number],
            title: [String,Number],
            value: [String,Number]
        },
        data: function() {
            return {
                originValue : this.value
            };
        },
        template:`<div :class="value == label ? 'layui-unselect layui-form-radio layui-form-radioed':'layui-unselect layui-form-radio'">
                            <i  :class="value == label ? 'layui-anim layui-icon layui-anim-scaleSpring':'layui-anim layui-icon'" @click="changeValueHandle(label)">{{value == label ? '':''}}</i>
                            <div>{{title}}</div>
                      </div>`,
        methods: {
            changeValueHandle(value) {
                this.$emit("input", value);
            }
        }
    });
    
  6. 对应以上的html代码

    radio

     <tl-radio label="1" title="小红书1" v-model="targetValue" ></tl-radio>
     <tl-radio label="2" title="小红书2" v-model="targetValue" ></tl-radio>
    

    checkbox

    <tl-checkbox :label="1" title="小红书1" v-model="targetValue" ></tl-checkbox>
    <tl-checkbox :label="2" title="小红书2" v-model="targetValue" ></tl-checkbox>
    
  7. 基本用的都是这三个组件,若有不完善,请指出,共同进步。

  8. 最后:其他还有不少没实现,比如日期组件

参考文献

https://www.jianshu.com/p/e805baa1574e 主要参考这个

https://www.jb51.net/article/140765.htm

https://www.jianshu.com/p/973cae0263ef 知识补充

https://www.cnblogs.com/024-faith/p/select.html 解决多个select 前一个不关闭问题

https://juejin.im/post/5b03e610f265da0b873ad64e 完整案例

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值