天天看點

【vuejs深入一】深入學習vue指令,自定義指令解決開發痛點

寫在前面

   一個好的架構需要經過血與火的曆練,一個好的工程師需要經過無數項目的摧殘。

  最近部落客我沉澱了幾個月,或者說懶了幾個月。然而大佬的指點總是一針見血,能夠讓人看到方向。是以我現在有覺得,一個好的學習環境指的一定是有個能指點你的大佬。大佬水準的高低決定了今後技術的學習難易。

v-model指令

       vue.js的定義是一個mvvm架構,将它發揮到極緻能夠極大的提升工作效率。在vuejs中,指令(directive)無疑是最關鍵,最重要的一環之一,官方api自帶的指令提供了非常友善的方式,将常見的編碼場景進行提煉,使用這些指令能令人感到愉悅。

  v-model

    資料綁定指令,它最常見的用法是可以将指定的data對象中的屬性綁定到一個form元素中,例如:

<div id="app">
        <div class="directives">
          <input type="text" v-model="text" name="" value="">
          {{text}}
        </div>
      </div>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
      <script type="text/javascript">
          new Vue({
            el: '#app',
            data: function(){
              return {
                  text: 'hello World'
              };
            },

          })
      </script>      
【vuejs深入一】深入學習vue指令,自定義指令解決開發痛點

上面的代碼,我們在data對象裡建立了一個text屬性,在标簽<input>中使用v-model綁定到text,這時候這個input輸入框會和text屬性進行同步。當你修改input中的值,text屬性值随之改變,然後這個改變被綁定到元素的value值上。

它的内部原理使用了html5的oninput事件,上面的代碼經過内部操作,其實可以表示成:

<div id="app">
        <div class="directives">
          <input type="text" :value="text" @input="setValue" name="" value="">
          {{text}}
        </div>
      </div>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
      <script type="text/javascript">
          new Vue({
            el: '#app',
            data: function(){
              return {
                  text: 'hello World'
              };
            },
            methods:{
              setValue:function($event){
                this.text = $event.target.value;
              }
            }
          });
      </script>      

注意這段:

<input type="text" :value="text" @input="setValue" name="" value="">      

v-model其實隻是一個文法糖,它與angular的model是不同的。  vue中其實它通過解析,在@input事件中設定響應,在響應中修改text的值,然後再通過綁定屬性v-bind綁定value同步value值,看到這裡你應該

對v-model有了更深入的了解了吧,那麼這個知識點對我們有什麼幫助呢? 

從這裡我們可以看出,v-model不僅僅可以綁定form元素,它還可以綁定元件:

<div id="app">
        <div class="directives">
          <demo-el v-model="text"></demo-el>
          <input type="text" v-model="text" name="" value="">
        </div>
      </div>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
      <script type="text/javascript">
          Vue.component("demo-el",{
            props:["value"],
            template:'<div style="color:green">{{value}}</div>'
          });
          new Vue({
            el: '#app',
            data: function(){
              return {
                  text: 'hello World'
              };
            },
            methods:{
            
            }
          });
      </script>      
【vuejs深入一】深入學習vue指令,自定義指令解決開發痛點

上面代碼我們使用vue-component定義一個元件,叫demo-el,它接受一個prop屬性,這裡為什麼是value呢? 結合上面的v-model原理再看。

<!--可以看成這樣-->
<demo-el :value="text" @input="setValue"></demo-el>      
原來是這樣,解析model時,綁定的就是value屬性,傳入元件就是prop啦。

v-model不能直接綁定的元素相信大家一定遇到過,那就是checkbox  radio。

在建立類似複選框或者單選框的常見元件時,v-model就不好用了。這裡部落客用自定義元件解決這個問題,

ps:現在最新版本的vue解決了一部分問題,v-model作用在checkbox上時可以綁定對應的true或者false了,但是它還不完美,例如在多選功能上,我們往往希望直接綁定選擇的多個值,而不是true或者false。
      

v-checkmodel 自定義指令實作

我們希望checkbox能夠根據自己的定義實作true和false的自由轉換,例如我們在項目json中,0是false,1是true,亦或者是 '是'是true,'否'是false,這要怎麼實作呢,
平時我們開發可能會在watch中監控屬性,例如:
      
{
 ......
  watch:{
       check:function(n){
          if(n){
              this.checktext = '是',
           }
       }
   }  
}      
我們需要手動判斷n的true或false,并且在請求到資料是需要将      
'是'      
'否'

轉換成 true false,我們可以用自定義指令來解決這個問題。
      
Vue.directive("checkmodel",{
            inserted:function(el,binding,vnode){
              var value = binding.value.value;
              var condition = binding.value.condition;
              if(condition[value] != undefined){
                el.checked = condition[value];
              }
               el.addEventListener("click",function(){
                 for(var name in condition){
                   if(condition[name] === this.checked){
                     binding.value.value = name;
                   }
                 }
              },false);
            }
          });      

我們建立了一個自定義指令,名稱叫checkmodel,它根據api接受三個參數,el【标簽對象】,binding綁定對象,vnode,node節點對象。

然後我們在下面規定擷取了綁定對象的value,綁定對象的condition表達式,然後将表達式的值綁定給el的checked,最後建立click監聽事件,當點選時根據表達式的值進行綁定轉換。

最後它的使用方法就像下面這樣:

<div id="app">
        <div class="directives">
          <input type="checkbox" v-checkmodel="check" name="" value="">
          {{check.value}}
        </div>
      </div>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
      <script type="text/javascript">
        
          new Vue({
            el: '#app',
            data: function(){
              return {
                  check:{
                    value:"1",
                    condition:{
                      "1":false,
                      "2":true
                    }
                  }
              };
            },
            methods:{

            }
          });
        
      </script>      

我們指定1是false,2是true,然後通過v-checkmodel綁定到checkbox,在點選時候,指令會根據condition中的值轉換true和false;

【vuejs深入一】深入學習vue指令,自定義指令解決開發痛點

你也可以基于這個中心思想,定制自己的指令,使它契合你的業務。例如我可以定義一個全局condition這個屬性,統管全局的字典轉換。

【vuejs深入一】深入學習vue指令,自定義指令解決開發痛點

(此圖代碼未經測試... gif錄制太大,修改思想呈現就好)

寫在後面

  mvvm架構和webpack的出現确實改變了前端的開發方式,使得學習前端變成了一門有着深入學問的課題。在我們日常開發中應該不斷地學習,歸納,總結,尋找新的思想,對原有的代碼有好的補充和好的改進。

       寫的不好,謝謝大家觀看。 後續有空會新增更多關于開發的知識分享。  

       如果你有什麼疑問,你可以聯系我,或者在下方評論。

========================================================

轉載請注明出處。

繼續閱讀