Vue——子級向父級傳遞參數


這里不考慮ref的使用,通過ref的方式,可以解決大部分問題,但是就和寫html一樣,不到萬不得已你不會使用id,

而且極端場合下,如何給組件設置id,本身就是一個難題。

 

業務場景:

我們設計一個表單組件,需要用戶填寫年齡,因此有個輸入框,我們使用 v-model 綁定年齡字段,
顯然,年齡不能超過200,因此組件還必須給出校驗位,當年齡超過200,校驗位就置成false,
因為校驗位是在組件內部憑空產生的,父組件如何獲取校驗位就成了一個難題。

 

(表單不會只有1個輸入框,因此很難設置 ref )

 

方案1:實現v-model

簡單的實現方案,就是實現自定義組件的 v-model 功能,缺點就是 v-model 只能綁定一個值。

(當然,這個方案不適合前面提到的案例,你可以考慮綁定一個對象,而不是一個值,因此列為一種解決方案。)

方案2:傳遞對象

props使用Object類型,父組件將一整個對象傳遞給子控件,父子組件都可以對參數進行修改、取值。
以下面代碼為例,<data-table>組件的參數是一個Object類型,父子組件只要約定好參數中的內容即可。

這或許是最優解了,寫法上不會太過另類,而且,Vue也不會阻止子組件修改Object的字段值

 

感覺上,這種做法似乎有些脫離了Vue設計初衷,Vue不會阻止子組件修改Object參數的內容,
同時,Vue 不會主動偵聽 Object 字段的變化,最直接的問題,就是頁面數據可能不發生聯動了,
不過即便不聯動,使用watch、computed也能解決問題,辦法總比困難多,主要也看編程如何取舍了。

 

<template xmlns="http://www.w3.org/1999/html">
  <data-table :table="table">
  </data-table>
</template>

<script>
    import DataTable from '@/components/widget/DataTable.vue'

    export default {
        components: {
            DataTable
        },
        data() {
            return {
                table: {
                    //分頁配置
                    url: undefined
                    , page: 1
                    , limit: 10
                    , enabledSelection: true
                    , resultParser: undefined
                    , data: [{
                        date: '2016-05-02',
                        name: '王小虎',
                        address: '上海市普陀區金沙江路 1518 弄',
                        isDisabled: false,
                        select: 1,
                        image: 'http://www.baidu.com'
                    }]
                }
            }
        }
    }
</script>

 

方案3:使用provide

與方案2基本一致,不過不用props,而是使用provide,也是將一整個對象傳遞給子控件。

兩種做法,應用場景有些不同。 

 

案例:

可以參考 element-ui 的 table 設計,table 和 column 一般會在代碼中同時出現,
我們只把數據傳遞給了 table 組件,但是 column 明顯也獲取了我們的數據,
我們並沒有看到 table 將數據傳遞給 column。

 

其他人看不到父子組件之間傳遞參數,但是子組件確確實實獲得了父組件的參數,
如果也希望設計這樣的組件,這時候就要用到 provide,provide 能起到暗度陳倉的效果,悄悄地就把參數傳給了子組件。

父級控件

通過provide,將自己的參數傳遞到子級控件。

<script>
    import FormInput from './FormInput.vue'

    export default {
        name: "fast-form"
        , provide() {
            return {
                formGroup: this.formGroup
            };
        }
    }      
<script>

 

子級控件

通過inject接收父級傳遞的參數。

<script>
    export default {
        name: "form-input"
        , inject: ['formGroup']
        , created: function () {
            //給formGroup增加一個事件回調,此處不符合VUE數據單向數據流的設計要求,但是滿足普通JS語法
            let currentWidget = this;
            for (let i = 0; i < currentWidget.formGroup.length; i++) {
                if (currentWidget.formGroup[i].name === this.name) {
                    currentWidget.formGroup[i].isValid = function () {
                        return currentWidget.checkFormInputValidity();
                    }
                }
            }
        }, methods: {
            /**
             * 比較當前值是否有效
             */
            checkFormInputValidity: function (value) {
            }
        }
    }        
<script>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM