vue2組件之select2調(diào)用的示例代碼
目前,項目中使用了純前端的靜態(tài)項目+RESTFul接口的模式。為了更好的對數(shù)據(jù)進行操作,前端使用了vue2的mvvm功能,但是由于不是單頁面應(yīng)用,所以,并沒有涉及到其它的如vue-route等功能,也未使用webpack等編譯功能,所以,也沒有使用.vue文件功能。這時候,如果用到控件,則多數(shù)從原jquery的組件中選擇。
select下拉搜索選擇
這次的需求調(diào)研與設(shè)計是原來做winform開發(fā)的同事,由于用慣了devexpress這個控件庫,所以,對于searchlookupeditor這個控件情有獨鐘,所以,在設(shè)計的時候,許多地方都用到。
最初實現(xiàn)
最初,我使用了select2綁定select標簽,設(shè)定其change事件 ,在事件中修改對應(yīng)的vue的data值,同時,在vue中設(shè)定watch``data中被綁定的屬性,屬性值發(fā)生變化,則修改對應(yīng)的dom的val,然后再觸發(fā)select2的change事件。當然,這種對應(yīng)關(guān)系,我在select標簽上放了一個data-vuep來保存其與vue屬性的對應(yīng)關(guān)系,并放在全局的select2vue和dom2vue中。
//mounted中的部分代碼
select2vue = {};
$("select").each(function (index, item) {
var s2 = $(item).select2({
language: "zh-CN", //設(shè)置 提示語言
width: "100%", //設(shè)置下拉框的寬度
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);
},
//通用函數(shù)
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>
為什么要用一個data-vuep來將數(shù)據(jù)與vue的屬性關(guān)聯(lián)呢,因為我發(fā)現(xiàn),select2初始化了這個select標簽之后,修改這個標簽的值無法觸發(fā)修改vue對應(yīng)的v-model的屬性。所以,只能用這個方法。
最終形成的結(jié)果是:
select2到vue.editor.P1:
1.select2被選擇某一項,觸發(fā)其change事件。
2.select2的change事件修改vue.editor.P1的值。
3.vue.editor.P1的值被修改,觸發(fā)watch,watch又引發(fā)select2的change事件,但是,select2內(nèi)部監(jiān)控到選擇和之前的一致,所以,不再執(zhí)行change事件的委托。
上面這種流程一定程度是實現(xiàn)了數(shù)據(jù)的雙向綁定,但是,非常復雜。在后續(xù)的使用中發(fā)現(xiàn),在mounted中無法為select2默認值,必須在mounted中調(diào)用setTimeout生成一個定時執(zhí)行的事件來執(zhí)行數(shù)據(jù)綁定操作,才會觸發(fā)上述流程,達到設(shè)定觸始值的效果。
使用vue指令
經(jīng)過一番掙扎,覺得上面這種方式還是不行。
上述方案不好的原因如下:
1.vue事件中的代碼操作了dom,這樣,在生命周期上可能會出現(xiàn)問題,特別是后來使用了setTimeout之后,生命周期變得更加不可控制。
2.每增加一個select組件,都需要增加 html標簽、watch,而且,html 標簽和watch既不是傳統(tǒng)的寫法,也不是vue的寫法,而是發(fā)明了一種新的東西,這破壞了開發(fā)體驗。
3.維護性比較差,當想刪除一個select的時候,必須要去watch里面去找與html中data-vuep相等的屬性監(jiān)控方法,并將其刪除掉。
4.兼容性不好,本方案選擇將頁面所有的select全部用select2初始化了一次,使得不論是否需要的,都會被影響;其次,如果不統(tǒng)一初始化,那么又多出了在mounted中為每一個select寫初始化代碼的工作,同時,也要為每個select取一個id。
為了解決這個問題,我又找到了最初看到的那個vue使用指令和select2的整合的例子。網(wǎng)上有好多,我不知道版權(quán)是誰的,姑且上我最先看到的那個吧。http://www.dhdzp.com/article/125654.htm
原文中的代碼如下:
<!DOCTYPE html>
<html>
<head>
<title>vue select2 封裝</title>
<link 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>結(jié)果:{{ 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>
作者也說了,對vue2.x的雙向綁定機制不了解,希望路過的大神幫幫忙。
我不是vue2的大神,甚至連新手都不算,只能說是初學者。我對代碼進行了調(diào)整,當然,也是操作了dom,但是由于封裝在指令里面了,使用人員不需要再次操作,不涉及到開發(fā)人員操作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代碼
<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>
經(jīng)過好幾天的研究,終于我發(fā)現(xiàn)在作者原來的代碼的update中,加入修改el的val值,然后再觸發(fā)select2的change事件,就可以了。而在使用方面,只需要給加一個v-select2即可,v-model以及option的配置都依照vue2的推薦方式,原封不動。之所以加了一個空的option是因為如果不加,默認select2是選擇第一個選項的,但是,由于未知原因,與vue.editor.P1并不同步。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Vue.js 2.0中select級聯(lián)下拉框?qū)嵗?/a>
- 淺談Vue Element中Select下拉框選取值的問題
- vue.js select下拉框綁定和取值方法
- vue select二級聯(lián)動第二級默認選中第一個option值的實例
- vue select選擇框數(shù)據(jù)變化監(jiān)聽方法
- vue 自定義 select內(nèi)置組件
- vue select組件的使用與禁用實現(xiàn)代碼
- 使用Vue自定義指令實現(xiàn)Select組件
- 詳解Vue 動態(tài)添加模板的幾種方法
- Vue動態(tài)控制input的disabled屬性的方法
- vue動態(tài)生成dom并且自動綁定事件
- vue中動態(tài)select的使用方法示例
相關(guān)文章
vue中監(jiān)聽input框獲取焦點及失去焦點的問題
這篇文章主要介紹了vue中監(jiān)聽input框獲取焦點,失去焦點的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
記一次用ts+vuecli4重構(gòu)項目的實現(xiàn)
這篇文章主要介紹了記一次用ts+vuecli4重構(gòu)項目的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05

