自开发vue插件笔记 1》插件定义

121 阅读2分钟

代码

/**vue form 插件 */
(function (window, document, Vue, Number, String, Function, Array, Object) {
   // Vue.pr
    //Vue.component('vf-input', {
    //    props: ['value'],
    //    template: '<input  v-bind:value="value" v-on:input="$emit(\'input\', $event.target.value)" />',
    //    computed: {
    //        validateState: function () {

    //        }
    //    }
    //});
    
    //复选框
    Vue.component('vf-checkbox', {
        model: {
            prop: 'value',
            event: 'change'
        },
        props: ['value', 'truevalue','falsevalue'],
        template: '<input type="checkbox" v-bind:checked="ckValue"  v-bind:value="value" v-on:change="onChagne($event.target);" />',
        created: function () {
            var vm = this;
            if (vm.truevalue == undefined) { vm.truevalue = true; }
            if (vm.falsevalue == undefined) { vm.falsevalue = false; }
            vm.ckValue = vm.truevalue == vm.value ? true : false;
        },
        data: function () {
            return {
                ckValue: false
            }
        },
        methods: {
            onChagne: function (target) {  
                var vm = this;
               var v = target.checked ? vm.truevalue : vm.falsevalue;
                vm.$emit('change', v);
            }
        },
        watch: {
            value: function (val) {
                this.ckValue = this.truevalue == val ? true : false;
            }
        }
        
    });
    
    //分页
    //以下设置vf-page
    Vue.component('vf-page',
        {
            //props: ['searchmodel'],
            props: {
                searchmodel: Object,    //searchmodel对象
                searchmethod: Function,  //点击执行函数
            },
            data: function () {
                return {
                    searchitem: this.searchmodel
                }
            },
            template: '<div class="page-wrap">\
            <div class= "page-left" >\
                <span>共 {{searchmodel.Count}} 条/{{searchmodel.TotalPage}}页</span>\
                <div class="page-select">\
                    <select class="input-inner" v-model="searchmodel.PageSize">\
                        <option v-bind:value="item" v-for="item in searchmodel.Pages">{{item}}条/每页</option>\
                    </select>\
                </div>\
                <span>\
                    前往\
                <div class="page-input">\
                        <input type="number" min="1" max="1000" v-model="searchmodel.PageIndex" class="input-inner">\
                </div>页\
                <button type="button" class="btn-go" v-on:click="refreshData()">跳转</button>\
            </span>\
        </div>\
                <div class="page-right">\
                    <span v-on:click="frontPage()">«</span>\
                    <span  v-on:click="prevPage()">上一页</span>\
                    <span  v-on:click="nextPage()">下一页</span>\
                    <span  v-on:click="lastPage()">»</span>\
                </div>\
    </div>'
            ,
            mounted: function () {
                var vm = this;
                //vm.searchmodel.PageIndex = 1; //当前页数
                //vm.searchmodel.Count = 0; //总条数
                //vm.searchmodel.PageSize = 10; //分页大小
                //vm.searchmodel.TotalPage = 1; //总页数
                //vm.searchmodel.Pages = [10, 20, 30, 50]; //分页数组
            }
            , methods: {
                frontPage: function () {
                    var vm = this;
                    vm.searchmodel.PageIndex = 1;
                    vm.refreshData();
                },
                lastPage: function () {
                    var vm = this;
                    vm.searchmodel.PageIndex = vm.searchmodel.TotalPage;
                    vm.refreshData();
                },
                nextPage: function () {
                    var vm = this;
                    if (vm.searchmodel.PageIndex < vm.searchmodel.TotalPage) {
                        vm.searchmodel.PageIndex++;
                        vm.refreshData();
                    }
                },
                prevPage: function () {
                    var vm = this;
                    if (vm.searchmodel.PageIndex > 1) {
                        vm.searchmodel.PageIndex--;
                        vm.refreshData();
                    }
                },
                refreshData: function () {
                    var vm = this;
                    if (vm.searchmodel.PageIndex < 1 || vm.searchmodel.PageIndex > vm.searchmodel.TotalPage) {
                        return;
                    }
                    if (vm.searchmethod) {
                        vm.searchmethod();
                    }
                }

            }
        });

    //下拉框
    Vue.component('vf-select', {
        model: {
            prop: 'value',
            event: 'myChange'
        },
        template: "<select v-bind:value='value' v-on:change='onChagne($event.target);'> <option v-for='option in vfoptions' v-bind:value='option[valuefield]' \
               v-text='option[textfield]'></option>  </select>",
        props: {
            value: [String, Number],
            "vfoptions": { type: Array, default: [] },
               valuefield: { type: String, default: "" },
            textfield: { type: String, default: "" },
            listkey: { type: String, default: "" },
        },
        watch: {
            vfoptions: function (list) {
                var vm = this;
                if (list.length > 0) { //默认第一个
                    vm.$emit('myChange', list[0][vm.valuefield]);
                }
            }
        }
        ,methods: {
            onChagne: function (target,row) {
                var vm = this;
                vm.$emit('myChange', target.value);
                vm.$emit('change', target.value, row);
            }
        }
    });
    
    //带搜索下拉框
    Vue.component('vf-select2', {
        props: {
            value: String,
            "vfoptions": {
                type: Array,
                default: function () {
                    return []
                }
            },
            "textfield": String,
            "pinyinfield": String,
            inputclass: String,
        },
        data: function () {
            return {
                isOpen: false,
                itemList: [],
                filterValue:"",
                selectedItem: {},
            }
        },   // $emit(\'input\', $event.target.value)  
        computed: {
            myInputClass: function () {
                return 'form-control ' + (this.inputclass || "");
            }
        },
        template: '<div class="vf-select dropdown" v-bind:class=\'{"open":isOpen}\'  >\
            <div class= "dropdown-toggle input-data-warp" >\
            <label> \
            <input v-bind:class="myInputClass" v-bind:value="filterValue"  v-on:input="onInput($event.target.value)" \
        v-on:keyup="filterItem($event)" v-on:focus="filterFocus($event);" v-on:blur="blur" />\
       <span class="icon-span" ><i class="glyphicon glyphicon-triangle-bottom"></i></span> </label> \
                         </div> \
            <ul class="dropdown-menu">\
            <li v-for=\'item in itemList\'><a v-on:mousedown.prevent.stop="selectItem(item)">{{item[textfield]}}</a></li>\
            </ul>\
                                </div>',
        created: function () {
            this.filterValue = this.value;
            //点击组件以外的地方,收起
            var vm = this;
        }
        , watch: {
            value: function (val) {
                this.filterValue = val;
            },
        }
        , methods: {
            onInput: function (filterValue) {
                var vm = this;;
                vm.$emit('input', filterValue);
            }
            , filterItem: function (e) {
                var vm = this;
                var searchvalue = e.currentTarget.value;
                if (!searchvalue) {  vm.itemList = vm.vfoptions; return; }
                vm.itemList = [];
                if (vm.pinyinfield) {
                    for (var i = 0, len = vm.vfoptions.length; i < len; i++) {
                        var text = vm.vfoptions[i][vm.textfield]; var  pinyinText = vm.vfoptions[i][vm.pinyinfield]; 
                        if (text.indexOf(searchvalue) != -1 || pinyinText.indexOf(searchvalue) > -1) {
                            vm.itemList.push(vm.vfoptions[i]);
                        }
                    }
                } else {
                    for (var i = 0, len = vm.vfoptions.length; i < len; i++) {
                        var text = vm.vfoptions[i][vm.textfield];
                        if (text.indexOf(searchvalue) != -1 ) {
                            vm.itemList.push(vm.vfoptions[i]);
                        }
                    }
                }
            
            }
            , filterFocus: function (e) {
                var vm = this;
                vm.isOpen = true;
                vm.filterItem(e);
            }
            , selectItem: function (item) {
                var vm = this;
                //赋值
                var oldItem = vm.selectedItem;
                vm.selectedItem = item;
                vm.filterValue = item[vm.textfield];
                //触发input给外面model赋值
                vm.onInput(vm.filterValue);
                vm.isOpen = false;
                //触发change事件
                vm.$emit("change", item, oldItem);
            }
            , blur: function () {
                var vm = this;
                var searchvalue = vm.filterValue;
                vm.$emit("blur", searchvalue);
                //失去焦点关闭
                vm.isOpen = false;
            }
        }
    });

    //以下queryselect组件
    Vue.component("vf-queryselect", {
        model: {
            prop: 'value',
            event: 'mychage'
        },
        //v-bind:vfvalue='valuefield'
        template: "<vf-select2 v-bind:vfoptions='inneroptions'  v-bind:textfield='textfield' \
                v-model='innername' v-bind:pinyinfield='pinyinfield'   v-on:change='change' v-on:blur='blur' ></vf-select2>",
        props: {
            value: [String, Number],
            modelname: { type: String, default: "" },
            valuefield: { type: String, default: "" },
            textfield: { type: String, default: "" },
            listkey: { type: String, default: "" },
            vfoptions: { type: Array, default: null },
            pinyinfield: String
        },
        inject: ['getData'],
        //  props: ["modelvalue", "modelname", "valuefield", "textfield", "listkey"],
        data: function(){
            return {
                inneroptions: [],
               innervalue: null,
               innername: null,
            }
        }
      , created: function () {
          var vm = this;
          if (vm.vfoptions) {
              vm.inneroptions = vm.vfoptions;
          } else { 
            vm.getData(vm.listkey, function (data) {
                vm.inneroptions = data;
              });
          }
          vm.innervalue = vm.value;
            vm.innername = vm.modelname;  //赋与初始的值
        },
        watch: {
            //外面改变内部也改变
            value: function (val) {
               this.innervalue = val;
            },
            modelname: function (val) {
                this.innername = val;
             },
        },
        methods: {
            onUpdate: function (v, n) {
                var vm = this;
                //1更改选中的值
              //  vm.innervalue = v;
              //  vm.innername = n;
                //2 抛出到外面的model
                vm.$emit('mychage',v);
                vm.$emit('update:modelname',n);
            },
            change: function (item,oldItem) {
                //选中处理
                var vm = this;
                //1更改选中的值 //2 抛出到外面的model
                vm.onUpdate(item[vm.valuefield], item[vm.textfield])
               
                vm.$emit("change", item, oldItem);
            }
            , blur: function (inputValue) {
                var vm = this;
                //为空表示删除
                if (!inputValue) {
                    vm.onUpdate("", "");
                }  //value没值表示未选中
                else if (!vm.innervalue || vm.innervalue == "0") {
                    vm.onUpdate("", "");

                }
            }
        }
    });

   //日期选择框
    Vue.component('vf-datepick', {
        model: {
            prop: 'value',
            event: 'myChange'
        },
        props: ['value','vfoption'],
        template: "<div class='input-data-warp'><label> \
<input  v-bind:value='innervalue' class='form-control' v-on:focus='onDatePick' /> \
<span class='icon-span' ><i class='datepick-img'></i></span></label></div>",
        data: function () {
            var vm = this;
            return {
                innervalue: "",
                dpoption: {
                    skin: 'twoer',
                    dateFmt: 'yyyy-MM-dd',
                    onpicked: function (dp) {
                        vm.innervalue = dp.cal.getNewDateStr();
                        vm.onUpdate(vm.innervalue,'picked');
                        return false;
                    },
                    oncleared: function () {
                        vm.innervalue = ""; vm.onUpdate(vm.innervalue,'cleared');
                    }
                }
            }
        },
        created: function () {
            var vm = this;
            vm.innervalue = vm.value;
            if (typeof (vm.vfoption) == "object") {
                for (var key in vm.vfoption) {
                    vm.dpoption[key] = vm.vfoption[key];
                }
            }
        },
        watch: {
            //外面改变内部也改变
            value: function (val) {
                this.innervalue = val;
            }
        },
        methods: {
            onUpdate: function (v,eventName) {
                var vm = this;
                vm.$emit('myChange', v);
                if (eventName) { 
                    vm.$emit(eventName, v);
                }
            }
            , onDatePick: function () {
                var vm = this;
                WdatePicker(vm.dpoption);
            }
        }
    });

    //以下插件可编辑表格
    var VueFormComponent = function () {

        //创建输入框
        this.createTextBox = function (formCom, bindField, funcChange, isdisabeled, funcBlur) {
            var obj = {};
            var extendOption = {name:"vft-textbox"};
            var name = bindField.substring(bindField.lastIndexOf('.') + 1);
            //设置方法
            extendOption.props = {
                myValue: [String, Number, Boolean],
                valueEmit: Function
            };
            var html = "<div><input type='text' class='form-control inline-form-control' v-bind:value='myValue' v-on:input='input($event.target.value)'  v-on:change='change($event.target.value)'  ></div>";
            extendOption.template = html;
            //extendOption.data = function () {
            //    return {
            //        myValue: "",
            //    }
            //};
            extendOption.methods = {
                change: function (val) {
                    if (funcChange) { funcChange(val); }
                },
                input: function (val) {
                //    if (bindField) eval("formCom.vm." + bindField + " = val");
                    this.myValue = val;
                    var editRow = this.valueEmit(val);//发射出去,返回要修改的model
                    editRow.DataRow[name] = val;
                }
            };
            obj.componentName = extendOption.name;
            obj.type = "TextBox";
            obj.fieldName = name;
            var  extendComponent = Vue.extend(extendOption);
            obj.extendComponent = extendComponent;
            return obj;
        }

        //带搜索的下拉
        this.createDropList = function (formCom, bindNameField, bindValueFields, listSource, callBack, filterfield) {
            var obj = {};
            var extendOption = { name: "vft-droplist" };
            var name = bindNameField.substring(bindNameField.lastIndexOf('.') + 1);
            var filterfield = filterfield || name;
            //设置方法
            extendOption.props = {
                myValue: [String, Number, Boolean],
                valueEmit: Function
            };
            extendOption.template = "<vf-select2 inputclass='inline-form-control' v-bind:vfoptions='vfoptions' textfield='" + filterfield +"' \
                v-model='innername' v-on:change='change' v-on:blur='blur' ></vf-select2>";
            extendOption.data = function () {
                return {
                    vfoptions: [],
                    innername: null,
                    selectedItem: {}
                }
            }
            extendOption.created = function () {
                //给vfoption 赋值
                var vm = this;
                if (typeof listSource == "function") {
                    listSource(function (data) {
                        vm.vfoptions = data;
                    });
                } else if(Vue.isArray(listSource)){
                    vm.vfoptions = listSource;
                } else if (typeof listSource == "string") {
                    vm.vfoptions = formCom.vm[listSource];
                }
                vm.innername = vm.myValue;
            }
            extendOption.watch = {
                myValue: function (val) {
                    this.innername = val;
                }
            }
            extendOption.methods = {
                onUpdate: function (inputV, item) {
                    var vm = this;
                    //1更改选中的值
                    vm.innername = inputV;
                    //2 更改外面的值
                    var editRow = vm.valueEmit(inputV,item);
                    editRow.DataRow[name] = inputV;
                    //更改其他字段
                    if (bindValueFields) {
                        for (var i = 0; i < bindValueFields.length; i++) {
                            var f = bindValueFields[i];
                            if (item && item[f]) { editRow.DataRow[f] = item[f] } else {
                                editRow.DataRow[f] = "";
                            }
                        }
                    }

                   

                },
                change: function (item, oldItem) {
                    //选中处理
                    var vm = this;
                    //1更改选中的值 //2 抛出到外面的model
                    vm.selectedItem = item;
                    vm.onUpdate(item[filterfield], item)
                    var editRow = vm.valueEmit();
                    if (callBack) { callBack(item, editRow); }
                    
                }
                , blur: function (inputValue) {
                    var vm = this;
                    //为空表示删除
                    if (!inputValue) {
                        vm.onUpdate("", {});
                    }  //value没值表示未选中
                    else if ($.isEmptyObject(vm.selectedItem)) {
                        vm.onUpdate("", {});

                    }
                }
            }


            obj.componentName = extendOption.name;
            obj.type = "DropList";
            obj.fieldName = name;
            var extendComponent = Vue.extend(extendOption);
            obj.extendComponent = extendComponent;
            return obj;
        }

        //日期
        this.createDatePick = function (formCom, bindNameField, dateFmt, onpicked) {
            var obj = {};
            //var extendOption = { name: "vft-datapick" };
            var name = bindNameField.substring(bindNameField.lastIndexOf('.') + 1);
            if (!dateFmt) {
                dateFmt = 'yyyy-MM-dd';
            }
            var extendOption = {
                props: {
                    myValue: [String, Number, Boolean],
                    valueEmit: Function
                },
                template: "<div class='input-data-warp'><label> \
<input  v-bind:value='myValue' class='form-control inline-form-control' v-on:focus='onDatePick' /> \
<span class='icon-span' ><i class='datepick-img'></i></span></label></div>",
                data: function () {
                    var vm = this;
                    return {
                        dpoption: {
                            skin: 'twoer',
                            dateFmt: dateFmt,
                            onpicked: function (dp) {
                                vm.onUpdate(dp.cal.getNewDateStr(), 'picked');
                                return false;
                            },
                            oncleared: function () {
                            vm.onUpdate("", 'cleared');
                            }
                        }
                    }
                },
                created: function () {
                    var vm = this;             
                },
                methods: {
                    onUpdate: function (v, eventName) {
                        var vm = this;
                        var editRow = vm.valueEmit(v);
                        editRow.DataRow[name] = v;
                        if (onpicked) { onpicked(v);  }
                    }
                    , onDatePick: function () {
                        var vm = this;
                        WdatePicker(vm.dpoption);
                    }
                }
            }

            obj.componentName = extendOption.name;
            obj.type = "DatePick";
            obj.fieldName = name;
            var extendComponent = Vue.extend(extendOption);
            obj.extendComponent = extendComponent;
            return obj;
        }
        //选择框
        this.createCheckBox = function (formCom, bindNameField, callBack,truevalue,falsevalue) {
            var obj = {};
            var name = bindNameField.substring(bindNameField.lastIndexOf('.') + 1);
            if (truevalue == undefined) { truevalue = true; }
            if (falsevalue == undefined) { falsevalue = false; }
            extendOption=  {
                props: {
                    myValue: [String, Number, Boolean],
                    valueEmit: Function
                },
                template: '<input type="checkbox" class="form-control inline-form-control" v-bind:checked="ckValue"  v-bind:value="myValue" v-on:change="onChagne($event.target);" />',
                created: function () {
                            var vm = this;
                            vm.ckValue = truevalue == vm.myValue ? true : false;
                        },
                data: function () {
                    return { ckValue: false }
                },
                methods: {
                    onChagne: function (target) {
                        var vm = this;
                        var v = target.checked ? truevalue : vm.falsevalue;
                        var editRow = vm.valueEmit(v);
                        editRow.DataRow[name] = v;
                        if (callBack) { callBack(v);}
                    }
                },
                watch: {
                    myValue: function (val) {
                        this.ckValue = truevalue == val ? true : false;
                    }
                }

            }

            obj.componentName = extendOption.name;
            obj.type = "CheckBox";
            obj.fieldName = name;
            var extendComponent = Vue.extend(extendOption);
            obj.extendComponent = extendComponent;
            return obj;
        }

    }

    window.VueFormComponent = VueFormComponent;
})(window, document, Vue, Number, String, Function, Array, Object);








使用

vf-queryselect

      <vf-queryselect class="com-input-txt" v-model="SearchModel.UserID" v-bind:modelname.sync="SearchModel.PersonName"
                                         listkey="CMAllPersonList" valuefield="UserID" textfield="PersonName" ></vf-queryselect>
                                         
  //listkey  provide注入的服务  

vf-datepick

      <vf-queryselect class="com-input-txt" v-model="SearchModel.data" ></vf-queryselect>
    //需要引入my97datepick 

VueFormComponent


var comfactory = new VueFormComponent();

 comfactory.createTextBox(formCom, "CellPhone");
 //创建一个动态组件