組件(2):使用Prop下發數據

數據下發

組件實例的做用域是相互獨立的,父、子組件之間沒法進行數據的共享。
若是想在子組件模板中使用父組件的數據,能夠經過Prop將父組件的數據下發到子組件。子組件用props選項聲明它預期的數據。javascript

爲了傳遞數據,父組件必須先在子組件自定義標籤的特性上綁定數據,綁定的值分兩種狀況解析:html

  • 字面量 prop="value"
  • 表達式(動態綁定) v-bind:prop="expression"
  • 表達式特例 v-bind="Object"
new Vue({
    el: '#app-1',
    data: {
        parentMsg: 'root\'s dynamic data',
        parentObj: {
            text:'hello vue!',
            isShow: true
        },
    },
    components: {
        'component-1': {
            props: ['expectMsg','expectDynamicMsg','expectObj','text','isShow'],
            template: '\
            <div>\
                <p>{{expectMsg}}</p>\
                <p>{{expectDynamicMsg}}</p>\
                <p v-show="expectObj.isShow">{{expectObj.text}}</p>\
                <p v-show="isShow">{{text}}</p>\
            </div>'
        }
<div id="app-1">
    <!-- 字面量綁定、動態綁定、動態綁定一個對象、動態綁定特例 -->
    <component-1 expect-msg="static data"
                 v-bind:expect-dynamic-msg="parentMsg" 
                 v-bind:expect-obj="parentObj" 
                 v-bind="parentObj">
    </component-1>
</div>

這裏分別做了幾種綁定的示例:vue

  • 把字符串"static data"綁定到子組件的propsexpectMsg
  • 把父組件屬性parentMsg動態綁定到子組件的expectDynamicMsg特性上
  • 把父組件中的一個對象parentObj動態綁定到子組件的expectObj特性上
  • 把父組件中的parentObj對象的屬性text、isShow綁定到子組件的textisShow特性上

注意:要下發一個數字給子組件不能使用字面量綁定,字面量下發的都是字符串。所以須要動態綁定java

<component v-bind:some-number="1">

Prop驗證

當要對下發數據作驗證或在無數據時設置默認值,子組件選項props就須要使用一個對象替換數組。
簡單的狀況:express

props:{
    someProp:String
}

下發數據必須是一個字符串數組

複雜點能夠設置默認值與驗證器,如:app

new Vue({
    el: '#app-2',
    data:{
        message:{
            title:'prop驗證',
            text:'父組件數據'
        }
    },
    components: {
        'component-2': {
            props: {
                propObj:{
                    type:Object,
                    //下發對象的title屬性必須是個字符串
                    validator:function(value){
                        return typeof value.title === "string"
                    },
                    //下發數據爲一個數組或對象,設置的默認值必須由一個函數返回
                    default:function(){
                        return {title:'prop驗證',text:'數組/對象的默認值應當由一個工廠函數返回'}
                    }
                }
            },
            template: '<div><h5>{{propObj.title}}</h5><p>{{propObj.text}}</p></div>'
        }
    }
})
<div id="app-2">
    <component-2 v-bind:prop-obj="message"></component-2>
</div>

type屬性也能夠是一個函數,使用instanceof驗證。驗證在子組件實例建立以前進行,所以驗證裏的任何函數都沒法使用子組件實例屬性。ide

更多類型驗證 Prop驗證函數

Prop的單向綁定和雙向綁定

下發數據實際上就是完成一個數據綁定的過程,把組件間的特定數據綁定在一塊兒,默認狀況下爲單向綁定,子組件的數據對於父組件是透明的,而父組件的數據變化則會引起子組件數據的變化。ui

new Vue({
    el: '#app-3',
    data: {
        content: "please input..."
    },
    components: {
        'component-3': {
            props:['txt'],
            template:'<div><input v-model="txt"></div>'
        }
    }
})
<div id="app-3">
    <input v-model="content">
    <br/>
    <component-3 v-bind:txt="content"></component-3>
</div>

clipboard.png

父組件經過Prop下發數據,將父組件屬性content和子組件特性txt綁定在一塊兒,在第一文本框輸入值改變content的內容,子組件的txt會跟隨變化,顯示在第二個文本框中。

clipboard.png

若是在子模板第二個文本框輸入,修改txt的值時,父組件控制的第一個文本框內容不會改變。

clipboard.png

並在控制檯給出警告,說不要修改props選項中的值,做爲代替,可讓prop的值賦予data或者computed屬性使用。所以能夠像下面這樣用data替代prop做爲一個局部變量。

'component-3': {
    props:['txt'],
    template:'<div><input v-model="txtData"></div>',
    data:function(){
        return {txtData:this.txt}
    }
}

若只考慮輸出不考慮輸入,也可使用計算屬性替代

'component-3': {
    props: ['txt'],
    template: '<div><input v-model="txtComputed"></div>',
    computed: {
        txtComputed:function() {
            return this.txt
        }
    }
}

非Prop特性

組件的做者卻並不總能預見到組件被使用的場景。因此,組件能夠接收任意傳入的特性,這些特性都會被添加到組件的根元素上,而不須要定義響應的props

var vm = new Vue({  
    el: '#app-4',
    components: {  
        "component-4": {  
            template: "<button class='btn-sm'>hello vue!</button>"  
        }  
    }  
});
<div id="app-4">
    <component-4 data-title="learn vue" class="btn-info"></component-4>
</div>

渲染結果

<button class="btn-sm btn btn-info" data-title="learn vue">hello vue!</button>

其中data-titleclass就是非Prop特性。
由於沒有在組件中定義props,所以也沒法去引用它們,做用目前不明顯。

從渲染結果還能夠發現,class特性的值由子組件模板和父模板定義的特性合併而成,對於classstyle是這樣合併結果。但對於多數組件來講,傳遞給組件的值會覆蓋組件自己設定的值。

相關文章
相關標籤/搜索