使用Vue 3.0,你可能不再需要Vuex了

开发 前端
Vuex 是一个很棒的状态管理库。它很简单,并与 Vue 集成的非常好。为什么会有人放弃 Vuex ? 原因可能是即将发布的 Vue3 版本公开了底层的响应式系统,并介绍了构建应用程序的新方法。新的响应式系统非常强大,它可以直接用于集中的状态管理。

 

使用 Vue 3.0,你可能不再需要Vuex了

前言

Vuex 是一个很棒的状态管理库。它很简单,并与 Vue 集成的非常好。为什么会有人放弃 Vuex ? 原因可能是即将发布的 Vue3 版本公开了底层的响应式系统,并介绍了构建应用程序的新方法。新的响应式系统非常强大,它可以直接用于集中的状态管理。

你需要状态共享吗?

在某些情况下,多个组件之间的数据流转变得非常困难,因此需要集中的状态管理。这些情况包括:

  • 多个组件使用相同数据的
  • 组件深嵌套

如果以上情况都不成立,答案很简单,你不再需要状态共享了。

但是,如果你有以上一种情况呢?最直接的答案就是使用 Vuex 。这是一个久经考验的解决方案,而且效果不错。

但是,如果你不想添加其他依赖项或发现设置过于复杂怎么办?新的Vue3 版本以及 Composition API 可以通过其内置方法解决这些问题。

新的解决方案

共享状态必须符合两个条件:

  • 响应式:当状态改变时,使用它们的组件也应更新
  • 可用性:可以在任何组件中访问状态

响应式

Vue3 通过众多功能公开了其响应式系统。你可以使用 reactive 函数创建响应式变量(替代方法是 ref 函数)。

  1. import { reactive } from 'vue' 
  2. export const state = reactive({ counter: 0 }); 

从 reactive 函数返回的 Proxy 对象是可以跟踪其属性更改的对象。在组件模板中使用时,当响应值发生更改时,组件都会重新渲染。

  1. <template> 
  2.   <div>{{ state.counter }}</div> 
  3.   <button type="button" @click="state.counter++">Increment</button> 
  4. </template> 
  5.  
  6. <script>  import { reactive } from 'vue'
  7.  
  8.   export default { 
  9.     setup() { 
  10.       const state = reactive({ counter: 0 }); 
  11.       return { state }; 
  12.     } 
  13.   };</script> 

可用性

上面的示例对于单个组件非常有用,但是其他组件无法访问状态。为了克服这个问题,你可以使用 provide 和 inject 方法,使 Vue 3 应用中任何指都能访问到。

  1. import { reactive, provide, inject } from 'vue'
  2.  
  3. export const stateSymbol = Symbol('state'); 
  4. export const createState = () => reactive({ counter: 0 }); 
  5.  
  6. export const useState = () => inject(stateSymbol); 
  7. export const provideState = () => provide( 
  8.   stateSymbol,  
  9.   createState() 
  10. ); 

当您将 Symbol 作为键和值传递给 provide 方法时,该方法中的任何子组件都可以使用该值。Symbol 提供和检索值时,key 使用相同的名称。

使用 Vue 3.0,你可能不再需要Vuex了

这样,如果你在最顶层的组件上提供值,那么它将在所有组件中可用。另外,还可以在主应用程序实例上调用 provide 。

  1. import { createApp, reactive } from 'vue'
  2. import App from './App.vue'
  3. import { stateSymbol, createState } from './store'
  4.  
  5. const app = createApp(App); 
  6. app.provide(stateSymbol, createState()); 
  7. app.mount('#app'); 
  8.  
  9. <script> 
  10.   import { useState } from './state'
  11.  
  12.   export default { 
  13.     setup() { 
  14.       return { state: useState() }; 
  15.     } 
  16.   }; 
  17. </script> 
 

让代码更加健壮

上面的解决方案有效,但有一个缺点:你不知道是谁修改了什么。状态可以直接更改,没有限制。

你可以使用 readonly 函数将状态包装起来,用以保护状态。它覆盖了在Proxy 对象中传递的变量,该代理对象阻止任何修改(在尝试修改时发出警告)。这些变化可以由能够访问可写存储的单独函数来处理。

  1. import { reactive, readonly } from 'vue'
  2.  
  3. export const createStore = () => { 
  4.   const state = reactive({ counter: 0 }); 
  5.   const increment = () => state.counter++; 
  6.  
  7.   return { increment, state: readonly(state) }; 

外部将只能访问只读状态,并且只有导出的函数可以修改可写状态。

通过保护状态免受不必要的修改,新解决方案相对接近 Vuex。

总结

通过使用 Vue 3 的响应式系统和依赖项注入机制,我们已经从本地状态转变为可以在较小的应用程序中替代 Vuex 的集中状态管理。

现在我们有;一个状态对象,该对象是只读的,并且可以对模板的更改作出响应。状态只能通过特定的方法来修改,比如 Vuex 中的 actions/mutations。可以使用 computed 函数定义其他 getter 。

Vuex 具有更多的功能,例如模块处理,但有时我们并不需要。

 

责任编辑:庞桂玉 来源: code秘密花园
相关推荐

2020-07-28 08:28:07

JavaScriptswitch开发

2019-12-31 13:12:14

5G智能手机操作系统

2014-09-30 16:03:35

iStick容量iPhone

2022-04-21 08:01:34

React框架action

2021-05-20 07:26:21

工具Vuex Vue.js

2022-09-27 15:03:43

Java测试工具

2022-03-31 06:18:21

WiFi 6EWiFi 6

2009-06-12 09:30:56

EJB3.0Spring+Hibe

2012-11-23 10:57:44

Shell

2020-09-18 14:01:21

vue3.0

2023-02-27 09:20:24

绝对定位CSS

2023-01-29 09:46:47

Dialog弹窗模态

2022-04-25 20:27:08

iOS 16iOSiPhone 6s

2015-08-13 09:03:14

调试技巧

2021-01-05 11:22:58

Python字符串代码

2020-01-29 19:40:36

Python美好,一直在身边Line

2019-11-20 10:25:06

sudoLinux

2021-07-12 07:59:06

安全 HTML 属性

2020-03-05 11:10:18

Left join数据库MySQL

2016-10-19 15:10:18

点赞
收藏

51CTO技术栈公众号