Vue-5個進階屬性(指令等)

Gen1usG發表於2020-01-31

Vue-5個進階構造屬性

本章介紹:directive、mixin、extend、provide&inject這5個Vue的進階構造屬性。

Directive-指令

  • 什麼是指令?

    其實之前我們就已經學習了指令,如:v-ifv-for,類似這些以 v- 開頭的就是指令,而v-ifv-for這些屬於內建指令,除此之外我們還可以自定義指令。

  • 全域性自定義指令

    全域性自定義指令:在全域性作用域下自定義指令,同時這個指令也能夠用於全域性,即任何元件都能夠使用這個全域性指令。如要宣告多個全域性指令,多次呼叫Vue.directive

    // 宣告全域性指令,注意在全域性作用域下
    Vue.directive('x',directiveOptions)
    
    // 使用全域性指令,在任何元件中都可以使用 v-x
    <myComponent v-x ></myComponent>
    複製程式碼
  • 區域性自定義指令

    區域性自定義指令:在某個元件Vue物件下進行宣告,只能在該Vue元件的例項中使用。注意區域性宣告時的 directives

    // 宣告區域性指令
    <script>
        export default {
            ...
            directives:{
            	"x":directiveOptions,
            	"y":directiveOptions
        	}
        }
    </script>
    
    // 只能在該元件中使用區域性指令
    <template>
    	<div v-x v-y></div>
    </template>
    複製程式碼
  • directiveOptions

    在上面的宣告中,我們只是演示了指令的宣告,並沒有研究如何賦予指令功能,而指令的功能是通過directiveOptions中的5個鉤子函式來實現的。

    1. directiveOptions中的5個鉤子函式:
      1. bind:可以看成Vue中的created函式,即:當使用該指令的VNode(虛擬DOM)載入到記憶體中時執行的鉤子函式。
      2. inserted:被繫結元素插入父節點時呼叫。
      3. update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。
      4. componentUpdated:指令所在元件的 VNode 及其子 VNode 全部更新後呼叫。
      5. unbind:只呼叫一次,指令與元素解綁時呼叫。
    2. 鉤子函式被傳入的4個引數:(el,binding,vnode,oldVnode)
      1. 第一個引數el:指令所繫結的元素,可以用來直接操作DOM。
      2. 第二個引數binding:這是一個物件,包含下列屬性
        • name:指令名,不包括v-字首
        • value:指令的繫結值,如:v-on:click='sayhi',這個sayhi就是指令繫結值。
        • oldValue:指令繫結的前一個值,僅在 updatecomponentUpdated 鉤子中可用。無論值是否改變都可用。
        • expression:字串形式的指令表示式,如:v-on:click='sayhi',這裡'sayhi'就是指令表示式。
        • arg:傳給指令的引數,如:v-on:click='sayhi',這個click就是傳給指令的引數。
        • modifiers:一個包含修飾符的物件。 例如:v-my-directive.foo.bar 中,修飾符物件為 { foo: true, bar: true }
      3. 第三個引數vnode:Vue 編譯生成的虛擬節點。
      4. 第四個引數oldVnode:Vue 編譯生成的上一個虛擬節點。
  • 使用directiveOptions完整宣告一個指令

    下面我們通過一個小例子,來簡單實現Vue內建指令v-on的繫結事件的功能。

    new Vue({
        directives: {
            "myOn": {
                inserted: (el, info) => {
                    el.addEventListener(info.arg, info.value)
                }
            }
        }
    })
    複製程式碼
  • 指令的作用以及使用場景

    Vue元件/例項的主要用於資料繫結、事件監聽、DOM更新,而指令的作用主要是完成原生DOM操作

    當我們需要重複多次相同的原生DOM操作,或者是進行一些比較複雜的原生DOM操作時,可以藉助指令來完成。

mixins-組合

  • 什麼是mixins?

    簡單來說就是“複製”。有時候我們需要使用多次相同的元件,這些元件的程式碼幾乎一樣,為了節省程式碼量,我們可以將這些相同的部分提取出來,然後通過mixin組合到各自元件中。mixins中的操作會合併到其他Vue例項中後,當作一個整體執行:比如:mixin中沒有某個變數,但是其它Vue例項中有,這種情況下並不會報錯,因是先合併了才執行。

  • mixins的意義

    mixins可以減少data、methods、鉤子的重複使用。

  • mixins的使用

    // 相同部分提取 log.js
    export default {
        data(){
            return {
                a:'a'
            }
        },
        methods:{
            hw:function(){ console.log('helloWorld') }
        },
        created:function(){
        	console.log('created')
    	}
    }
    複製程式碼
    // 在元件中使用提取的部分 myComponent.vue
    import log from './log.js'
    export default {
        // 這裡是個陣列,說明可以使用多個mixins
        mixins:[log],
        data(){
       	 	return {
        		b:'b'
    		}
    	}
    }
    // 此時,這元件就可以使用mixins中的 a資料 ,hw方法 ,created ,以及自身的 b資料
    複製程式碼
  • mixins是智慧合併的

    相同data當前例項優先順序更高,而相同的鉤子函式則會把兩邊的操作都合併起來。

  • 全域性mixin

    Vue.mixin({mixin物件})
    複製程式碼

    注意:全域性mixin宣告時沒有s(mixin)。使用全域性mixin後,所有的元件包括App.vue都會預設合併這個全域性mixin,所以不建議使用全域性mixin。

extends-繼承

  • extends的作用

    extends的作用和mixins一樣,但是形式不同。

  • extends的使用

    1.區域性extends的使用

    // 宣告擴充套件內容
    const myVue = {}
    // 使用
    export default {
        // 注意這裡不是陣列
        extends:myVue,
        data(){ return {} }
    }
    複製程式碼
    1. 全域性extends的使用

      // 全域性宣告
      const myVue = Vue.extend({擴充套件內容})
      // 繼承式宣告Vue例項
      new myVue({vueOptions}) 
      複製程式碼
    2. extends與extends&mixins

      extends宣告的擴充套件內容還能夠使用extends和mixins。

      import log from './log.js' // mixin
      const com1 = {}
      
      const com2 = {
          extends:com1,
          mixins:[log]
      }
      複製程式碼

provide提供&inject注入

  • 什麼是provide和inject?

    上級元件可以通過provide傳遞data與method,而下級元件可以通過inject獲取上級元件傳遞的data與method。

    provide和inject能夠大範圍傳遞data和methods

  • provide和inject的使用方法

    // 上級元件
    export default {
        data(){
            return { n:'n'}
        },
        methods:{
            add(){
                console.log('add')
            }  
        },
        provide(){
            return {
                n:this.n,
                add:this.add
            }
        }
    }
    
    // 下級元件
    // 我們就可以在下級元件中,使用n與add
    export default {
        inject:['n','add']
    }
    複製程式碼
  • provide和inject使用細節

    傳遞的data時,父元件把自身data的地址複製了一份傳遞了,子元件能夠獲取data的值,但如果想在子元件中修改父元件的某些data(簡單型別如Number、String)是不允許的,因為我們修改的只是複製的變數的值。但是我們可以通過在子元件中呼叫父元件傳遞過裡啊的method來修改父元件的data,因為傳遞過來的method內部關聯的是父元件的data。

    但是如果父元件provide的data是一個物件,由於上級元件複製的是一個地址,所以子元件訪問的也是同一個物件,那麼在子元件中是能夠修改這個物件,進而影響到父元件的。不推薦傳遞一個provide一個物件,因為如果都使用這個方法,那麼在元件較多的情況下很難確定那個物件當前是出於什麼狀態。

相關文章