Vue.js+Laravel项目兄弟组件方法传值与数据同步实现方案
Vue兄弟组件跨组件数据同步实现方案
针对当前父组件下两个兄弟组件需要共享接口返回数据、且数据变更实时同步的需求,有3种可行实现,优先推荐第一种无额外依赖、符合Vue设计规范的方案。
方案1:状态提升(优先推荐)
核心逻辑:兄弟组件不能直接互相访问数据,把需要共享的状态上移到两者的共同父组件维护,遵循Vue单向数据流规则:父组件统一管理数据源,通过props向子组件传值,子组件通过事件向父组件通知数据变更,全程数据流可追溯,无额外依赖。
具体代码修改
- 修改父组件
在父组件中维护共享的图表数据、当前选中的图表类型,接收子组件抛出的更新事件,同时把数据下发给表格组件:
<template> <div> <h4>DATA ANALYSIS</h4> <!-- 传入当前选中类型,监听子组件的数据更新事件 --> <dataAnalysisGraph :chartType="chartType" @update:chartData="handleChartDataUpdate" /> <br> <hr> <!-- 把共享数据传给表格组件 --> <dataAnalysisTable :chartData="chartData" /> </div> </template> <script> export default { data() { return { chartType: '1', // 默认选中第一个选项 chartData: [] // 共享的图表数据 } }, methods: { handleChartDataUpdate(newData) { this.chartData = newData } } } </script>
- 修改dataAnalysisGraph子组件
移除组件内部私有维护的共享数据,接口请求成功后通过$emit把数据抛给父组件,选中的图表类型通过props接收:
<template> <div> <div> <select class="form-control select" @change="GenerateChart" v-model='chartType' > <option value="1">One</option> <option value="2">Two</option> <option value="3">Three</option> </select> </div> <br><br><br> <highcharts class="hc" :options="chartOptions" ref="chart"></highcharts> </div> </template> <script> export default { props: { chartType: { type: String, default: '1' } }, data() { return { // 仅保留组件自身需要的私有状态,比如图表配置项 chartOptions: {} } }, methods: { GenerateChart(){ this.axios .get(`api/${this.chartType}`) .then(response => { // 数据抛给父组件,同时更新自身图表配置 this.$emit('update:chartData', response.data) this.chartOptions = { // 基于response.data生成highcharts配置 series: { data: response.data } } }); }, }, created() { this.GenerateChart(); }, }; </script>
- 修改dataAnalysisTable子组件
移除自身维护的重复data,通过props接收父组件传入的共享数据,数据变更时会自动响应更新:
<template> <div> {{chartData}} </div> </template> <script> export default { props: { chartData: { type: Array, default: () => [] } } }; </script>
方案2:全局事件总线(轻量临时方案)
如果不想调整父组件逻辑,可以通过Vue事件总线实现跨组件事件传递,适合小型项目快速实现:
- 先在项目Vue入口文件注册全局事件总线:
// Vue2 写法 import Vue from 'vue' Vue.prototype.$bus = new Vue() // Vue3 写法 const app = createApp(App) app.config.globalProperties.$bus = app
- 修改dataAnalysisGraph组件,接口请求成功后在总线上派发数据更新事件:
// GenerateChart方法内 .then(response => { this.data = response.data; this.$bus.$emit('chartDataUpdate', response.data) })
- 修改dataAnalysisTable组件,监听总线事件更新自身数据,注意销毁时解绑事件避免内存泄漏:
<script> export default { data() { return { data: [] } }, mounted() { this.$bus.$on('chartDataUpdate', (newData) => { this.data = newData }) }, beforeDestroy() { this.$bus.$off('chartDataUpdate') } } </script>
注意:该方案数据流是隐式的,项目规模变大后事件来源难以追溯,调试成本高,不推荐中大型项目使用。
方案3:全局状态管理(适合复杂扩展场景)
如果后续该数据分析模块会有更多组件共享这份数据,可以引入状态管理库统一维护:Vue2项目用Vuex,Vue3项目用Pinia。把图表数据存在全局store中,dataAnalysisGraph请求完数据后提交更新到store,dataAnalysisTable直接从store中取数,依赖状态管理的响应式能力自动同步更新。该方案适合后续功能迭代多的中大型项目,当前两个组件的场景下使用会稍显冗余。
内容的提问来源于stack exchange,提问作者Vincent Dapiton
相关产品推荐
相关产品推荐

