最近在整理專案中程式碼,在元件之間資料傳遞遇到了問題,所以做了這次總結,如有不對的地方,望指正。
父元件如何將資料傳到子元件中
父元件可以通過Prop
傳遞資料到子元件中。
這裡需要注意的是:
-
Prop
是單向繫結的:當父元件的屬性變化時,將傳導給子元件,但是反過來不會。這是為了防止子元件無意間修改了父元件的狀態,來避免應用的資料流變得難以理解。 -
每次父元件更新時,子元件的所有
Prop
都會更新為最新值。這意味著你不應該在子元件內部改變 prop。如果你這麼做了,Vue 會在控制檯給出警告。
在兩種情況下,我們很容易忍不住想去修改 prop 中資料:
Prop
作為初始值傳入後,子元件想把它當作區域性資料來用;
解決方法:定義一個區域性變數,並用 prop
的值初始化它:
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
複製程式碼
Prop
作為原始資料傳入,由子元件處理成其它資料輸出。
解決方法: 定義一個計算屬性,處理 prop 的值並返回:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
複製程式碼
PS:上邊的內容是vue
文件裡邊有說的,我只是把自己在專案中遇到的問題抽出來了。連結
栗子:
// 父元件 index.vue
<template>
<div class="content">
<child :lists="lists"></child>
</div>
</template>
<script>
import child from './child.vue';
export default {
components: {
child
},
data() {
return {
lists: []
};
},
mounted() {
this.lists = [{
name: '01',
content: 'hi,'
}, {
name: '02',
content: 'my name is Ellyliang'
}];
}
};
</script>
// 子元件 child.vue
<template>
<ul class="content">
<li v-for="(list, index) in getLists" :key="index" v-html="list.name + list.content"></li>
</ul>
</template>
<script>
export default {
props: ['lists'],
data() {
return {
getLists: this.lists
};
},
mounted() {
this.getLists.push({
name: '03',
content: '不要在乎內容,我就是測試'
});
}
};
</script>
複製程式碼
子元件如何將資料傳到父元件中
子元件可通過vm.$emit
將資料傳遞給父元件
vm.$emit
是啥
觸發當前例項上的事件。附加引數都會傳給監聽器回撥。 連結
栗子:
// 父元件 index.vue
<template>
<div class="content">
<child :lists="lists" @listenToChild="getChildMsg"></child>
</div>
</template>
<script>
import child from './child.vue';
export default {
components: {
child
},
data() {
return {
lists: []
};
},
mounted() {
this.lists = [{
name: '01',
content: 'hi,'
}, {
name: '02',
content: 'my name is Ellyliang'
}];
},
methods: {
getChildMsg(val) {
alert(val); // 'hello'
}
}
};
</script>
// 子元件 child.vue
<template>
<div class="content">
<ul class="lists">
<li v-for="(list, index) in getLists" :key="index" v-html="list.name + list.content"></li>
</ul>
</div>
</template>
<script>
export default {
props: ['lists'],
data() {
return {
getLists: this.lists
};
},
mounted() {
this.getLists.push({
name: '03',
content: '不要在乎內容,我就是測試'
});
setTimeout(() => {
this.$emit('listenToChild', 'hello');
}, 15000);
}
};
</script>
複製程式碼
子元件給父元件傳資料是不是也很方便。實現方法是就是在子元件中$emit
資料,然後在父元件中通過事件@事件名
接收值。
Event Bus
事件巴士這種方法,不僅能處理父子元件傳遞,子父元件傳遞,還是處理平級元件之間的數值傳遞。其實現方法就是在全域性new
一個vue
例項,然後傳值給bus
, 就是let bus = new vue();
。通過這個全域性的bus
中的$emit
, $on
等等去實現資料的傳遞。這樣處理有個問題,由於event bus
處理資料傳遞很方便,不管在哪裡都可以傳遞,這樣導致濫用,從而導致程式碼很難去理解。
Event Bus實現
let bus = new Vue();
// 觸發元件 A 中的事件
bus.$emit('id-selected', 1);
// 在元件 B 建立的鉤子中監聽事件
bus.$on('id-selected', function (id) {
// ...
});
複製程式碼
具體元件的封裝和使用,可參考vue-bus。
其它方式
除了以上3種方法,還有就是通過vuex
去處理資料的傳遞,但是我還沒有接觸,大家要感興趣,自己去學習。