vue2组件之select2调用的示例代码

网友投稿 419 2023-03-27


vue2组件之select2调用的示例代码

目前,项目中使用了纯前端的静态项目+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中。

//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

为什么要用一个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.ArdZLlMTVmvue事件中的代码操作了dom,这样,在生命周期上可能会出现问题,特别是后来使用了setTimeout之后,生命周期变得更加不可控制。

2.每增加一个select组件,都需要增加 html标签、watch,而且,html 标签和watch既不是传统的写法,也不是vue的写法,而是发明了一种新的东西,这破坏了开发体验。

3.维护性比较差,当想删除一个select的时候,必须要去watch里面去找与html中data-vuep相等的属性监控方法,并将其删除掉。

4.兼容性不好,本方案选择将页面所有的select全部用select2初始化了一次,使得不论是否需要的,都会被影响;其次,如果不统一初始化,那么又多出了在mounted中为每一个select写初始化代码的工作,同时,也要为每个select取一个id。

为了解决这个问题,我又找到了最初看到的那个vue使用指令和select2的整合的例子。网上有好多,我不知道版权是谁的,姑且上我最先看到的那个吧。//jb51.net/article/125654.htm


结果:{{ selectValue }}

我不是vue2的大神,甚至连新手都不算,只能说是初学者。我对代码进行了调整,当然,也是操作了dom,但是由于封装在指令里面了,使用人员不需要再次操作,不涉及到开发人员操作dom的情况,我还是可以接受的。

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代码


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:短信接口管理平台(短信接口什么意思)
下一篇:微信小程序 页面滑动事件的实例详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~