Vue自帶的通信方式非常郁悶,只能自上而下的進行數據綁定。一旦要反向通信或者廣播通信就要用到Vuex或者其它插件。但是這些東西實在太重了,煩躁,看著就不想用。于是自己寫了一個好使的。
實現原理:實現一個v-load指令和v-sync指令。用指令參數決定對應的同步標簽,指令值決定data的對應關系。例子:
<sender v-sync:abc="{id:'my_id',name:'my_name'}"></sender>
<receiver v-load:abc="{id:'your_id',name:'your_name'}"></receiver>
于是sender組件data中的my_id被同步到receiver中的your_id,my_name被同步到your_name。
實現原理:
1.在Vue中使用Vue.directive來定義指令,其中bind:function(el,binding,vNode)的第三個參數vNode指向當前Vue組件或實例的虛擬節點,當指令所在的html標簽正好是Vue實例或組件所在的標簽時,其componentInstance屬性指向Vue對象;當指令所在的html標簽是Vue實例或組件內部的普通html標簽時,其contex屬性指向其所在的Vue對象。
指令寫在一個Vue實例內的組件上可以看到,componentInstance對應的是一個VueComponent對象,及指令所在的組件,而contex對應一個Vue$3對象,及該組件所在的Vue實例。
2.當我們使用var scope = vNode.componentInstance || vNode.context;獲取到一個Vue對象時,可以使用scope.$watch()函數在指令中動態指定觀察對象。
3.在Vue中,使用Vue.set對其它組件或實例data中的屬性進行修改,能夠被該組件或實例動態響應。
以上是預備知識,下面上代碼:
Load.js
接著看Sync.js
進行js壓縮和混淆并取消開發環境下的錯誤提示之后的min版本
var postman={};Vue.directive("load",{bind:function(b,e,c){var f=e.arg;var a=c.componentInstance||c.context;var d=e.value;if(typeof postman[f]=="undefined"){postman[f]=[]}postman[f].push({vue:a,map:d})}});Vue.directive("sync",{bind:function(b,e,c){var f=e.arg;var a=c.componentInstance||c.context;var d=e.value;for(key in d){(function(g){a.$watch(d[g],function(i,h){for(targetKey in postman[f]){var k=postman[f][targetKey];var j=k.vue;var l=k.map[g];Vue.set(j,l,i)}},{deep:true})})(key)}}});
共計490字節
一個字:爽
測試結果:
注意:
只能指定data中的根屬性而不能指定子屬性,如:
return {title:'asdasd',content:'asdasd',writer:{name:''asdasd",profile:"asdasd"}};
對于這種,只能直接指定觀察writer而不能指定觀察profile。
*:其實是可以做到的,但是這樣一般夠用了。而且我懶。
另外,簡書的文本編輯器做的真是爛。UI明明做的不錯的說,結果整出這么個玩意兒,真是夠了。