需求:v现在有三个组件,爷爷,儿子,孙子。现在爷爷嵌套着儿子,儿子嵌套着孙子。现在孙子组件的数据更新了,要通知给爷爷组件,如何传递?
由于 Vue 2 遵循单向数据流,不推荐直接从孙子组件向爷爷组件传递数据,常见的做法有以下两种:通过事件层层传递和使用事件总线。
方法一:通过事件层层传递
这种方法是孙子组件触发一个自定义事件,将数据传递给儿子组件,儿子组件再触发一个自定义事件,将数据传递给爷爷组件。
孙子组件(
Grandson.vue
)<template> <div> <button @click="updateData">更新数据</button> </div> </template> <script> export default { methods: { updateData() { const newData = '这是更新后的数据'; // 触发自定义事件,将数据传递给父组件(儿子组件) this.$emit('dataUpdated', newData); } } }; </script>
儿子组件(
Son.vue
)<template> <div> <Grandson @dataUpdated="handleDataUpdated" /> </div> </template> <script> import Grandson from './Grandson.vue'; export default { components: { Grandson }, methods: { handleDataUpdated(newData) { // 触发自定义事件,将数据传递给父组件(爷爷组件) this.$emit('dataUpdated', newData); } } }; </script>
爷爷组件(
Grandfather.vue
)<template> <div> <Son @dataUpdated="handleGrandsonDataUpdated" /> <p>从孙子组件传来的数据:{{ grandsonData }}</p> </div> </template> <script> import Son from './Son.vue'; export default { components: { Son }, data() { return { grandsonData: '' }; }, methods: { handleGrandsonDataUpdated(newData) { // 更新数据 this.grandsonData = newData; } } }; </script>
方法二:使用事件总线
事件总线是一个全局的事件发射器,孙子组件可以通过它触发一个事件,爷爷组件可以监听这个事件。
创建事件总线(
eventBus.js
)import Vue from 'vue'; export const eventBus = new Vue();
孙子组件(
Grandson.vue
)<template> <div> <button @click="updateData">更新数据</button> </div> </template> <script> import { eventBus } from './eventBus.js'; export default { methods: { updateData() { const newData = '这是更新后的数据'; // 通过事件总线触发自定义事件 eventBus.$emit('grandsonDataUpdated', newData); } } }; </script>
爷爷组件(
Grandfather.vue
)<template> <div> <Son /> <p>从孙子组件传来的数据:{{ grandsonData }}</p> </div> </template> <script> import Son from './Son.vue'; import { eventBus } from './eventBus.js'; export default { components: { Son }, data() { return { grandsonData: '' }; }, created() { // 监听事件总线的自定义事件 eventBus.$on('grandsonDataUpdated', (newData) => { this.grandsonData = newData; }); }, beforeDestroy() { // 销毁事件监听器,防止内存泄漏 eventBus.$off('grandsonDataUpdated'); } }; </script>