前言Vuex是一个很棒的状态管理库。它很简单,并且与Vue.js集成得很好。为什么会有人放弃Vuex?原因可能是即将到来的Vue3版本暴露了底层的反应式系统并引入了构建应用程序的新方法。新的反应式系统非常强大,可以直接用于集中式状态管理。你需要状态共享吗?在某些情况下,多个组件之间的数据流转换变得非常困难,因此需要集中状态管理。这些情况包括:使用相同数据的多个组件组件的深度嵌套如果以上都不是,答案很简单,您不再需要共享状态。但是,如果你有上述情况之一怎么办?最直接的答案是使用Vuex。这是一个久经考验的解决方案,效果很好。但是,如果您不想添加额外的依赖项或发现设置太复杂怎么办?新的Vue3版本和CompositionAPI可以通过其内置方法解决这些问题。新的解决方案共享状态必须满足两个标准:反应性:当状态发生变化时,使用它们的组件也应该更新可用性:状态可以在任何组件中访问反应性Vue3通过众多功能公开其反应性系统。您可以使用反应函数创建反应变量(替代方法是ref函数)。import{reactive}from'vue';exportconststate=reactive({counter:0});从反应函数返回的Proxy对象是一个可以跟踪其属性变化的对象。当在组件模板中使用时,组件将在响应值更改时重新呈现。{{state.counter}}
增量可用性上面的例子对单个组件很有效,但是其他组件无法访问状态.为了克服这个问题,您可以使用provide和inject方法使其可供Vue3应用程序中的任何手指使用。import{reactive,provide,inject}from'vue';exportconststateSymbol=Symbol('state');exportconstcreateState=()=>reactive({counter:0});exportconstuseState=()=>inject(stateSymbol);exportconstprovideState=()=>提供(stateSymbol,createState());当您将Symbol作为键和值传递给provide方法时,该方法中的任何子组件都可以使用该值。Symbol在提供和检索值时使用相同的名称。这样,如果您在最顶层组件上提供一个值,它将在所有组件中可用。或者,可以在主应用程序实例上调用provide。import{createApp,reactive}from'vue';importAppfrom'./App.vue';import{stateSymbol,createState}from'./store';constapp=createApp(App);app.provide(stateSymbol,createState());app.mount('#app');制作代码moreRobust上面的解决方案可行,但有一个缺点:你不知道谁修改了什么。状态可以直接改变,没有限制。您可以通过使用只读函数包装它来保护状态。它会覆盖传递给Proxy对象的变量,从而防止任何修改(尝试修改时发出警告)。这些更改可以由具有可写存储访问权限的单独函数处理。import{reactive,readonly}from'vue';exportconstcreateStore=()=>{conststate=reactive({counter:0});constincrement=()=>state.counter++;return{increment,state:readonly(state)};}External将只能访问只读状态,只有导出的函数才能修改可写状态。通过保护状态免受不必要的修改,新解决方案相对接近Vuex。总结通过使用Vue3的反应系统和依赖注入机制,我们已经从本地状态转移到可以在较小的应用程序中替代Vuex的集中状态管理。现在我们有;一个状态对象,它是只读的并响应模板更改。状态只能通过特定方法修改,例如Vuex中的动作/突变。可以使用computed函数定义其他getter。Vuex有更多的功能,比如模块处理,但有时我们并不需要它。