如何優雅的封裝vue元件

萬奎發表於2019-03-23

如何優雅的封裝vue元件

在編寫元件時,最好考慮好以後是否要進行復用。一次性元件間有緊密的耦合沒關係,但是可複用元件應當定義一個清晰的公開介面,同時也不要對其使用的外層資料作出任何假設。 Vue 元件的 API 來自三部分——prop、事件和插槽:

  • Prop 允許外部環境傳遞資料給元件;
  • 事件允許從元件內觸發外部環境的副作用;
  • 插槽允許外部環境將額外的內容組合在元件中。

在開發過程中,結合 Vue 元件化的特性,開發通用元件是很基礎且重要的工作。通用元件必須具備==高效能、低耦合==的特性。

props(資料從父元件傳入)

通常的props是這樣定義的:

    props:['data','type','state']
複製程式碼

但是通用元件的的應用場景比較複雜,對 props 傳遞的引數應該新增一些驗證規則

    props:{
        data:{
            type: Array,
            required: true
        },
        type: [String, Number],
        state: {
            type: Boolean,
            default: false
        }
    }
複製程式碼

對於通過 props 傳入的引數,不建議對其進行操作,因為會同時修改父元件裡面的資料

// vue2.5已經針對 props 做出優化,這個問題已經不存在了

如果一定需要有這樣的操作,可以這麼寫:

    let myData = JSON.stringify(this.data);
    myData = JSON.parse(myData);
複製程式碼

為什麼不直接寫 let myData = this.data 呢?

因為直接賦值,並不能解除雙向繫結。改變 myData 的時候,會改變 this.data,父元件的 data 也會變

而通過 JSON 轉換之後,就能任性的操作了

在父元件處理事件

在通用元件中,通常會需要有各種事件, 比如核取方塊的 change 事件,或者元件中某個按鈕的 click 事件

這些事件的處理方法應當儘量放到父元件中,通用元件本身只作為一箇中轉

    //子元件中的方法
    hanleSubmit (data) {
        this.$emit('submit', data);
    }
複製程式碼
    //在父元件中處理
    <child-form @sumit='parentSubmit'></child-form>
複製程式碼

這樣既降低了耦合性,也保證了通用元件中的資料不被汙染
不過,並不是所有的事件都放到父元件處理

比如元件內部的一些互動行為,或者處理的資料只在元件內部傳遞,這時候就不需要用 $emit 了

使用插槽slot實現內容分發

一個通用元件,往往不能夠完美的適應所有應用場景

所以在封裝元件的時候,只需要完成元件 80% 的功能,剩下的 20% 讓父元件通過 solt 解決
比如一個彈框元件,彈框下班的操作按鈕,有可能是‘取消’,‘確定’,可能是‘重置’,‘提交’....按鈕的事件操作也不一樣,這種場景就適合用內容分發了。

    // 子元件
    <div class='modal'>
        <h3>標題</h3>
        <div class='con'>
            .......
        </div>
        <div class='act-group'>
            <slot name='buttonGroup'></slot>
        </div>
    </div>
複製程式碼
    // 父元件  
    <modal>
        <div slot='buttonGroup'>
            <button>取消</button>
            <button>確定</button>
        </div>
    </modal>
複製程式碼

相關文章