如何从Vue父实例继承props与函数实现全组件通用复用
现有实现的问题
你的思路不符合Vue的单向数据流设计规则:
- 父组件传递给子组件的props本身是只读属性,子组件不能直接赋值修改,所有对prop的修改都需要通知父组件由父组件完成更新
- 你当前的根组件代码并没有在调用
Page组件时显式传递loading属性,子组件实际是拿不到这个值的
可行实现方案
方案1:单向数据流修改(仅适合父子组件传值场景)
如果你只需要在根组件和Page组件之间共享这个变量,按照Vue规范修改代码即可:
- 根组件模板中传递prop和监听更新事件
<!-- 根组件模板 --> <Page :loading="loading" @update:loading="newVal => loading = newVal" />
- 子组件通过触发事件通知父组件修改值
// Page.vue mounted 逻辑修改 mounted() { setTimeout(() => { this.$emit('update:loading', true) }, 1000) }
方案2:全局状态管理(最推荐,适合全应用多组件共享状态)
Vue3官方推荐使用Pinia做全局状态管理,所有组件都可以直接读取、修改Store中定义的全局状态和方法:
- 注册Pinia到全局
// vue.js import { createApp } from 'vue' import { createPinia } from 'pinia' import Page from './vue-instances/Page' const app = createApp({ components: { Page } }) app.use(createPinia()) app.mount('#vue-app')
- 定义全局Store
// stores/common.js import { defineStore } from 'pinia' export const useCommonStore = defineStore('common', { state: () => ({ loading: false }), actions: { setLoading(val) { this.loading = val } } })
- 任意组件中使用
// Page.vue import { useCommonStore } from '@/stores/common' export default { data() { return { title: 'New Page' } }, mounted() { const commonStore = useCommonStore() setTimeout(() => { commonStore.setLoading(true) // 也可以直接赋值 commonStore.loading = true }, 1000) } }
方案3:依赖注入(适合跨层级传递,不需要全局共享的场景)
如果只需要在根组件后代中共享状态,可以用provide/inject避免逐层传prop:
// vue.js 根组件提供状态和修改方法 const app = createApp({ data() { return { loading: false } }, provide() { return { loading: Vue.computed(() => this.loading), setLoading: (val) => { this.loading = val } } }, components: { Page } })
// Page.vue 注入后使用 export default { inject: ['loading', 'setLoading'], mounted() { setTimeout(() => { this.setLoading(true) }, 1000) } }
内容的提问来源于stack exchange,提问作者PhilipCodeX
相关产品推荐
相关产品推荐

