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

deniro發表於2018-12-08

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

1 用法

假設父元件的模板包含子元件,我們可以通過 props 來正向地把資料從父元件傳遞給子元件。props 可以是字串陣列,也可以是物件。

html:

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

js:

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 引數名稱。

html:

<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: {}
});
複製程式碼

**注意:**如果使用的是字串模板,那麼可以忽略這個限制。

有時候,傳遞過來的資料來自於父級的動態資料,這是我們可以使用 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:''
	}
});
複製程式碼

效果:

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

這裡我們使用 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: {}
});
複製程式碼

效果:

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

元件中定義了 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: {}
});

複製程式碼

效果:

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

**注意:**在 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.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

相關文章