說說在 Vue.js 中如何實現組件間通訊

1 用法

假設父組件的模板包含子組件,咱們能夠經過 props 來正向地把數據從父組件傳遞給子組件。props 能夠是字符串數組,也能夠是對象。css

html:html

<div id="app">
    <deniro-component message=""嫦娥四號"成功發射升空 飛向月球背面要登錄"></deniro-component>
</div>
複製代碼

js:vue

Vue.component('deniro-component', {
	props: ['message'],
	template:
		'<div>{{message}}</div>'
});


var app = new Vue({
	el: '#app',
	data: {}
});
複製代碼

渲染結果:算法

<div id="app"><div>"嫦娥四號"成功發射升空 飛向月球背面要登錄</div></div>
複製代碼

組件中的 props 與 data 函數的區別是:props 中的數組來自於父級,而 data 函數是組件內定義的數據,因此它的做用域是組件自己。它們均可以在 template、computed 以及 methods 中使用。數組

若是須要傳遞多個數據,直接在 props 數組中定義便可。瀏覽器

由於 HTML 不區分大小寫,因此當使用 DOM 模板時,建議直接使用短橫分隔(kebab-case)的命名方式來定義 props 參數名稱。bash

html:app

<div id="app2">
    <deniro-component2 special-message="微軟向谷歌投降重構Edge 但IE瀏覽器爲什麼將長存"></deniro-component2>
</div>
複製代碼

js:函數

Vue.component('deniro-component2', {
	props: ['specialMessage'],
	template:
		'<div>{{specialMessage}}</div>'
});


var app2 = new Vue({
	el: '#app2',
	data: {}
});
複製代碼

**注意:**若是使用的是字符串模板,那麼能夠忽略這個限制。ui

有時候,傳遞過來的數據來自於父級的動態數據,這是咱們可使用 v-bind 來動態綁定 props 中的數據。

html:

<div id="app3">
    <input type="text" v-model="parentMessage">
    <deniro-component3 :message="parentMessage"></deniro-component3>
</div>
複製代碼

js:

Vue.component('deniro-component3', {
	props: ['message'],
	template:
		'<div>{{message}}</div>'
});


var app3 = new Vue({
	el: '#app3',
	data: {
		parentMessage:''
	}
});
複製代碼

效果:

這裏咱們使用 v-model 綁定了父級數據 parentMessage。因此當在輸入框中鍵入的內容,也會同步傳遞給子組件。

注意:若是不使用 v-bind 來傳遞數字、布爾對象、數組或者對象,那麼傳遞的僅僅是字符串!

html:

<div id="app4">
    <deniro-component4 :message="['a','b','c']"></deniro-component4>
    <deniro-component4 message="['a','b','c']"></deniro-component4>
</div>
複製代碼

js:

Vue.component('deniro-component4', {
	props: ['message'],
	template:
		'<div>參數類型:{{typeof message}};參數長度:{{message.length}}</div>'
});


var app4 = new Vue({
	el: '#app4',
	data: {}
});
複製代碼

輸出結果:

參數類型:object;參數長度:3 參數類型:string;參數長度:13

2 改變單向數據流

Vue2.x 中,經過 props 傳遞的數據是單向的,也就是說,若是父組件中的數據發生變化,那麼也會影響到子組件中的數據。

有時候,由於業務場景的要求,咱們須要改變這種單向數據流的設計。

2.1 做爲初始值

子組件把父組件傳遞過來的值做爲初始值,而後在本身的做用域內隨意修改與使用它。這能夠經過在子組件的 data 內定義一個新數據,用於引用父組件中的參數。

html:

<div id="app5">
    <deniro-component5 :init-value="0"></deniro-component5>
</div>
複製代碼

js:

Vue.component('deniro-component5', {
	props: ['initValue'],
	template:
		'<div>初始值:{{initValue}};<button @click="counter++">{{counter}}</button></div>',
	data:function () {
		return {
			counter:this.initValue
		}
	}
});

var app5 = new Vue({
	el: '#app5',
	data: {}
});
複製代碼

效果:

組件中定義了 counter,它被初始化爲傳入的 initValue,初始化以後,counter 就與 initValue 無關啦O(∩_∩)O~

2.2 轉換後傳入

有時候,咱們必須把 props 中的值轉換後傳入子組件,這能夠經過計算屬性來實現。

html:

<div id="app6">
    <deniro-component6 :border="5" :width="200"></deniro-component6>
</div>
複製代碼

js:

Vue.component('deniro-component6', {
	props: ['border', 'width'],
	template:
		'<div :style="style">一個算法通吃三大棋類</div>',
	computed: {
		style: function () {
			return {
				border: this.border + 'px solid red',
				width: this.width + 'px'
			}
		}
	}
});

var app6 = new Vue({
	el: '#app6',
	data: {}
});

複製代碼

效果:

**注意:**在 JS 中,對象與數組是引用類型,即子組件中定義的變量若是賦值的是這些類型,那麼改變這些變量的值,是會影響到父組件的!

3 驗證

咱們自定義的組件,若是須要提供給第三方使用,那麼最好進行參數驗證,這就須要用到對象寫法。若是驗證失敗,那麼會在瀏覽器的控制檯輸出警告日誌。

html:

<div id="app7">
    <deniro-component7 :a="'str'"></deniro-component7>
</div>
複製代碼

js:

<script src="https://cdn.bootcss.com/vue/2.2.2/vue.js"></script>
<script>
    Vue.component('deniro-component7',{
       props:{
           a:Number
       },
        template:
            '<div >{{a}}</div>',
    });

    var app7 = new Vue({
        el: '#app7',
        data: {}
    });
</script>
複製代碼

**注意:**這裏引入了開發版的 vue.js(生產版通常是 vue.min.js)。

控制檯輸出:

其它示例:

Vue.component('deniro-component8', {
	props: {
		//必須是數字類型
		a: Number,
		//數字類型或者字符串類型
		b: [Number, String],
		//布爾類型,默認值爲 true
		c: {
			type: Boolean,
			default: true
		},
		//字符串類型,必須傳值
		d: {
			type: String,
			required: true
		},
		//自定義
		e: {
			validator: function (v) {
				return v > 1;
			}
		}
	}
});
複製代碼

type 能夠爲這些類型:String、Number、Boolean、Object、Array、Function。


以上示例 DEMO

相關文章
相關標籤/搜索