vue3是否有一个“全局变量”,每个组件可以读取修改值且在app中使用的地方都是双向绑定的?

1. 运行环境#

vue3
windows10

2. 问题描述?#

我想在兄弟组件之间传递数据,甚至和父亲组件的兄弟组件传递数据

查询文档后了解到要通过父组件绑定数据,子组件通过 props 接收

但是这样子就太麻烦了,相当于每次传递数据都要来一遍这样子的操作

3. 您期望得到的结果?#

我就在想要是我可以配置一个全局变量 A,且这个变量可以被双向传递

那么只要子组件直接读取或者修改就行。

4. 您实际得到的结果?#

这样子可行吗?是否可以给个思路?

最佳答案

总结一下

vue3 的 store模式props逐级透传&依赖注入的区别

  • store模式 就是 vue3 通过 reactive() 来注册的一个全局状态
  • props逐级透传&依赖注入 相当于最顶级的父组件提供一个状态,其子组件共享

store 模式

vue3 的选项式 API 中,响应式数据是用 data () 选项声明的。在内部,data () 的返回值对象会通过 reactive () 这个公开的 API 函数转为响应式。

可以利用这一特性创建一个 js 文件,其他组件引用,并放置到组件的 data () 中,这样选项式 API 中,可以以 store.count 的方式直接访问 store 的值

// store.js
import { reactive } from 'vue'

export const store = reactive({
  count: 0
})

这里引用的时候需要 import { store } from './store.js' 写,而不是 import store from './store.js'

两者的区别:TODO

当组件 A 中修改 count 时,组件 B 中的 count 状态也会随之修改


props 逐级透传 & 依赖注入

假设有 A>B>C>D>E , 其中 A>B 代表 A 是 B 的父组件

当 E 组件需要 A 组件 中的数据的时候,这种情况下式利用 props 来逐级传递的是非常麻烦的

如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为 “prop 逐级透传”

此时引入 provide(提供)inject(注入) 的概念。

只要父组件定义一个 provide 选项,那么就可以通过 injectprovide 中的属性注入到需要的子组件中

下面是 vue3 选项式 API 的写法,子组件可以拿到父组件的值

// 父组件
export default {
    data(){
        return {
            msg: 'xxxx',
        }
    },
    provide(){
        return {
            message: this.msg
        }
    },
}

// 子组件

export default {
  inject: ['message'],
  created() {
    console.log(this.message) // injected value
  }
}

<template>
    <div> {{ this.message }} </div>
</template>

vuex 和 store模式的区别

还是借用这句话

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此 —— 如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

1年前 评论
讨论数量: 10
余胜军

直接 pinia 就好了

1年前 评论
sinmu (楼主) 1年前
sinmu (楼主) 1年前

透传 attribute 与依赖注入,认真去读一下这两个章节的文档

1年前 评论
sinmu (楼主) 1年前

感觉说的是 vuex

1年前 评论
sinmu (楼主) 1年前

总结一下

vue3 的 store模式props逐级透传&依赖注入的区别

  • store模式 就是 vue3 通过 reactive() 来注册的一个全局状态
  • props逐级透传&依赖注入 相当于最顶级的父组件提供一个状态,其子组件共享

store 模式

vue3 的选项式 API 中,响应式数据是用 data () 选项声明的。在内部,data () 的返回值对象会通过 reactive () 这个公开的 API 函数转为响应式。

可以利用这一特性创建一个 js 文件,其他组件引用,并放置到组件的 data () 中,这样选项式 API 中,可以以 store.count 的方式直接访问 store 的值

// store.js
import { reactive } from 'vue'

export const store = reactive({
  count: 0
})

这里引用的时候需要 import { store } from './store.js' 写,而不是 import store from './store.js'

两者的区别:TODO

当组件 A 中修改 count 时,组件 B 中的 count 状态也会随之修改


props 逐级透传 & 依赖注入

假设有 A>B>C>D>E , 其中 A>B 代表 A 是 B 的父组件

当 E 组件需要 A 组件 中的数据的时候,这种情况下式利用 props 来逐级传递的是非常麻烦的

如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为 “prop 逐级透传”

此时引入 provide(提供)inject(注入) 的概念。

只要父组件定义一个 provide 选项,那么就可以通过 injectprovide 中的属性注入到需要的子组件中

下面是 vue3 选项式 API 的写法,子组件可以拿到父组件的值

// 父组件
export default {
    data(){
        return {
            msg: 'xxxx',
        }
    },
    provide(){
        return {
            message: this.msg
        }
    },
}

// 子组件

export default {
  inject: ['message'],
  created() {
    console.log(this.message) // injected value
  }
}

<template>
    <div> {{ this.message }} </div>
</template>

vuex 和 store模式的区别

还是借用这句话

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此 —— 如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

1年前 评论

vue3 当然选择 pinia ,不要用 vuex 了

1年前 评论