vue2组件之select2调用的示例代码
对此感兴趣的朋友,看看idc笔记做的技术笔记!
目前,项目中使用了纯前端
这篇文章主要为大家详细介绍了vue2组件之select2调用的示例代码,具有一定的参考价值,可以用来参考一下。
对此感兴趣的朋友,看看idc笔记做的技术笔记!
目前,项目中使用了纯前端的静态项目+RESTFul接口的模式。为了更好的对数据进行操作,前端使用了vue2的mvvm功能,但是由于不是单页面应用,所以,并没有涉及到其它的如vue-route
等功能,也未使用webpack
等编译功能,所以,也没有使用.vue
文件功能。这时候,如果用到控件,则多数从原jquery的组件中选择。
select下拉搜索选择
这次的需求调研与设计是原来做winform开发的同事,由于用惯了devexpress
这个控件库,所以,对于searchlookupeditor
这个控件情有独钟,所以,在设计的时候,许多地方都用到。
最初实现
最初,我使用了select2绑定select标签,设定其change事件 ,在事件中修改对应的vue的data值,同时,在vue中设定watch``data中被绑定的属性,属性值发生变化,则修改对应的dom的val,然后再触发select2的change事件。当然,这种对应关系,我在select标签上放了一个data-vuep来保存其与vue属性的对应关系,并放在全局的select2vue和dom2vue中。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <code> //mounted中的部分代码 select2vue = {}; $( "select" ).each( function (index, item) { var s2 = $(item).select2({ language: "zh-CN" , //设置 提示语言 width: "100%" , //设置下拉框的宽度 theme: "classic" , placeholder: "请选择" }).on( "change" , function (e) { console.log(e); var v = $(e.target).val(); var p = $(e.target).attr( "data-vuep" ); eval ( "vue_cust_busi." + p + "='" + v + "';" ); //$(e.target).find("option").attr("selected",false); //$(e.target).find("option[value='"+v+"']").attr("selected",true); }); var p = $(item).attr( "data-vuep" ); select2vue[p] = s2; dom2vue[p] = item; }); setTimeout( function (){ vue_cust_busi.editor.ID_CUST= "3" ; vue_cust_busi.editor.NAME_CUST= "*有限责任公司" ; console.log( "修改" ); },10,null); //watch中的部分代码 "temp.P1" : function (val) { fire(arguments.callee.name.toString(), val); }, //通用函数 function fire(p, val) { $(dom2vue[p]).val(val); select2vue[p].trigger( "change" ); } //html <select data-vuep= "editor.P1" class = "form-control " > <option value= "" ></option> <option v- for = "yearOpt in yearOpts" v-bind:value= "yearOpt" >{{yearOpt}}</option> </select> </code> |
为什么要用一个data-vuep来将数据与vue的属性关联呢,因为我发现,select2初始化了这个select标签之后,修改这个标签的值无法触发修改vue对应的v-model的属性。所以,只能用这个方法。最终形成的结果是:
select2到vue.editor.P1:
1.select2被选择某一项,触发其change事件。2.select2的change事件修改vue.editor.P1的值。3.vue.editor.P1的值被修改,触发watch,watch又引发select2的change事件,但是,select2内部监控到选择和之前的一致,所以,不再执行change事件的委托。上面这种流程一定程度是实现了数据的双向绑定,但是,非常复杂。在后续的使用中发现,在mounted中无法为select2默认值,必须在mounted中调用setTimeout生成一个定时执行的事件来执行数据绑定操作,才会触发上述流程,达到设定触始值的效果。
使用vue指令
经过一番挣扎,觉得上面这种方式还是不行。
上述方案不好的原因如下:
1.vue事件中的代码操作了dom,这样,在生命周期上可能会出现问题,特别是后来使用了setTimeout之后,生命周期变得更加不可控制。2.每增加一个select组件,都需要增加 html标签、watch,而且,html 标签和watch既不是传统的写法,也不是vue的写法,而是发明了一种新的东西,这破坏了开发体验。3.维护性比较差,当想删除一个select的时候,必须要去watch里面去找与html中data-vuep相等的属性监控方法,并将其删除掉。4.兼容性不好,本方案选择将页面所有的select全部用select2初始化了一次,使得不论是否需要的,都会被影响;其次,如果不统一初始化,那么又多出了在mounted中为每一个select写初始化代码的工作,同时,也要为每个select取一个id。
为了解决这个问题,我又找到了最初看到的那个vue使用指令和select2的整合的例子。网上有好多,我不知道版权是谁的,姑且上我最先看到的那个吧。//www.idcnote.com/article/125654.htm
原文中的代码如下:
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <code> <!DOCTYPE html> <html> <head> <title>vue select2 封装</title> <link href= "https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel= "external nofollow" rel= "stylesheet" /> <script src= "https://unpkg.com/vue/dist/vue.js" ></script> <script src= "https://cdn.bootcss.com/jquery/2.2.4/jquery.js" ></script> <script src= "https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js" ></script> <style type= "text/css" > .content{ text-align: center; padding:50px; } .content *{ text-align: left; } .select{ width: 350px; } </style> </head> <body> <div class = "content" id= "vue-example" > <select class = "select" v-select2= 'options' v-model= "selectValue" ></select> <br/> <span>结果:{{ selectValue }}</span> </div> </body> <script type= "text/javascript" > Vue.directive( 'select2' , { inserted: function (el, binding, vnode) { let options = binding.value || {}; $(el).select2(options).on( "select2:select" , (e) => { // v-model looks for // - an event named "change" // - a value with property path "$event.target.value" el.dispatchEvent( new Event( 'change' , { target: e.target })); //说好的双向绑定,竟然不安套路 }); }, update: function (el, binding, vnode) { $(el).trigger( "change" ); } }); var vueApp = new Vue({ el: "#vue-example" , data: { selectValue: '你还没有选值' , options: { data: [ { id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 2, text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' } ] } } }); </script> </html> </code> |
作者也说了,对vue2.x的双向绑定机制不了解,希望路过的大神帮帮忙。
我不是vue2的大神,甚至连新手都不算,只能说是初学者。我对代码进行了调整,当然,也是操作了dom,但是由于封装在指令里面了,使用人员不需要再次操作,不涉及到开发人员操作dom的情况,我还是可以接受的。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <code> Vue.directive( 'select2' , { inserted: function (el, binding, vnode) { let options = binding.value || {}; $(el).select2(options).on( "select2:select" , (e) => { // v-model looks for // - an event named "change" // - a value with property path "$event.target.value" el.dispatchEvent( new Event( 'change' , { target: e.target })); //说好的双向绑定,竟然不安套路 console.log( "fire change in insert" ); }); }, update: function (el, binding, vnode) { for ( var i = 0; i < vnode.data.directives.length; i++) { if (vnode.data.directives[i].name == "model" ) { $(el).val(vnode.data.directives[i].value); console.log( "new value in update:" +vnode.data.directives[i].value); } } $(el).trigger( "change" ); console.log( "fire change in update" ); } }); //html代码 <select v-select2= "" v-model= "editor.P1" required= "required" class = "form-control " > <option value= "" ></option> <option v- for = "item in codes" v-bind:value= "item.NAME" >{{item.NAME}}</option> </select> </code> |
经过好几天的研究,终于我发现在作者原来的代码的update中,加入修改el
的val值,然后再触发select2的change事件,就可以了。而在使用方面,只需要给加一个v-select2即可,v-model以及option的配置都依照vue2的推荐方式,原封不动。之所以加了一个空的option是因为如果不加,默认select2是选择第一个选项的,但是,由于未知原因,与vue.editor.P1并不同步。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持php教程。
注:关于vue2组件之select2调用的示例代码的内容就先介绍到这里,更多相关文章的可以留意