文章转载自公众号:code秘密花园
Vuex
是一个很棒的状态管理库。它很简单,并与 Vue 集成的非常好。为什么会有人放弃Vuex
? 原因可能是即将发布的 Vue3
版本公开了底层的响应式系统,并介绍了构建应用程序的新方法。新的响应式系统非常强大,它可以直接用于集中的状态管理。
你需要状态共享吗?
在某些情况下,多个组件之间的数据流转变得非常困难,因此需要集中的状态管理。这些情况包括:
- 多个组件使用相同数据的
- 组件深嵌套
如果以上情况都不成立,答案很简单,你不再需要状态共享了。
但是,如果你有以上一种情况呢?最直接的答案就是使用 Vuex
。这是一个久经考验的解决方案,而且效果不错。
但是,如果你不想添加其他依赖项或发现设置过于复杂怎么办?新的Vue3
版本以及 Composition API
可以通过其内置方法解决这些问题。
新的解决方案
共享状态必须符合两个条件:
- 响应式:当状态改变时,使用它们的组件也应更新
- 可用性:可以在任何组件中访问状态
响应式
Vue3
通过众多功能公开了其响应式系统。你可以使用 reactive
函数创建响应式变量(替代方法是 ref
函数)。
import { reactive } from 'vue';
export const state = reactive({ counter: 0 });
从 reactive
函数返回的 Proxy
对象是可以跟踪其属性更改的对象。在组件模板中使用时,当响应值发生更改时,组件都会重新渲染。
<template>
<div>{{ state.counter }}</div>
<button type="button" @click="state.counter++">Increment</button>
</template>
<script>
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({ counter: 0 });
return { state };
}
};
</script>
可用性
上面的示例对于单个组件非常有用,但是其他组件无法访问状态。为了克服这个问题,你可以使用 provide
和 inject
方法,使 Vue 3
应用中任何指都能访问到。
import { reactive, provide, inject } from 'vue';
export const stateSymbol = Symbol('state');
export const createState = () => reactive({ counter: 0 });
export const useState = () => inject(stateSymbol);
export const provideState = () => provide(
stateSymbol,
createState()
);
当您将 Symbol
作为键和值传递给 provide
方法时,该方法中的任何子组件都可以使用该值。Symbol
提供和检索值时,key
使用相同的名称。
这样,如果你在最顶层的组件上提供值,那么它将在所有组件中可用。另外,还可以在主应用程序实例上调用 provide
。
import { createApp, reactive } from 'vue';
import App from './App.vue';
import { stateSymbol, createState } from './store';
const app = createApp(App);
app.provide(stateSymbol, createState());
app.mount('#app');
<script>
import { useState } from './state';
export default {
setup() {
return { state: useState() };
}
};
</script>
让代码更加健壮
上面的解决方案有效,但有一个缺点:你不知道是谁修改了什么。状态可以直接更改,没有限制。
你可以使用 readonly
函数将状态包装起来,用以保护状态。它覆盖了在Proxy
对象中传递的变量,该代理对象阻止任何修改(在尝试修改时发出警告)。这些变化可以由能够访问可写存储的单独函数来处理。
import { reactive, readonly } from 'vue';
export const createStore = () => {
const state = reactive({ counter: 0 });
const increment = () => state.counter++;
return { increment, state: readonly(state) };
}
外部将只能访问只读状态,并且只有导出的函数可以修改可写状态。
通过保护状态免受不必要的修改,新解决方案相对接近 Vuex
。
总结
通过使用 Vue 3
的响应式系统和依赖项注入机制,我们已经从本地状态转变为可以在较小的应用程序中替代 Vuex
的集中状态管理。
现在我们有;一个状态对象,该对象是只读的,并且可以对模板的更改作出响应。状态只能通过特定的方法来修改,比如 Vuex
中的 actions/mutations
。可以使用 computed
函数定义其他 getter
。
Vuex
具有更多的功能,例如模块处理,但有时我们并不需要。
以上就是W3Cschool字节宝
关于Vue 3.0 有了它,Vuex或许可以提前退休了的相关介绍了,希望对大家有所帮助。