Vue3中无需引入Vuex的替代方案

Vue3 中所提供组合 API、ref、reactive、provide、inject几大特性,可以支持完成全局状态管理能力,Vuex 是为 Vue 单独提供的状态管理插件,相对比较笨重,如果项目简单可以尝试替代

所属分类 WEB

相关标签 VueVuex状态

方案说明

在研读 Vue3 的指导文档的时候,我们会被反复提醒重大变化就是提供了组合式 API。

简单来说通过组合式 API,我们可以将 Vue 视图所依赖的数据和逻辑剥离出来。

而我们以前处理数据时,除了当前组件的数据还会有父组件传入的数据,以及使用 Vuex 进行管理的全局数据。

在官方文档中着重提供了一个父组件调用子组件的数据传递和响应性的 DEMO,我的第一反应就是这个方案完全可以替代 Vuex 进行全局状态管理。

PS:不知道为什么,官方没有提到这一点。或许并不推荐或害怕滥用行为?

思路梳理

考虑进行替代之前,我们需要梳理下全局状态管理能力的要点(可以参考 Vuex 的实现)。

  1. 全局访问(state):一个数据源所有的组件都能够访问读取。
  2. 全局更新(getters):当数据源产生变化时,所有组件都能够获取更新后的数据。
  3. 可控修改(mutations):既要能够随时随地被修改,又要能够可控的被修改。

我们需要看在 Vue3 中能够提供这些特性:

  1. 全局访问:在根组件中通过 provide 提供数据,在任意子组件中通过 inject 即可获取到相应的数据。
  2. 全局更新:在根组件中提供的数据通过 ref、reactive 修饰后返回的 Proxy 对象为响应式变量,当其产生变化后,组件会被重新渲染。
  3. 可控修改:在根组件中通过 provide 提供的数据利用 readonly 修饰,禁止外部直接修改,通过根组件将修改方法提供出来供调用。

既然我们发现全局状态管理的诉求在 Vue3 中能够充分实现,那就开始尝试吧。

我们单独规划一个目录用于创建全局数据,比如我放在 src/context 路径下。

其中用户全局数据放在 src/context/user.js,本文主要是提供方案,没有写过多的复杂逻辑。

import { reactive, provide, readonly, inject } from 'vue'

// 用户全局变量命名
const UserSymbol = 'USER'
// 用户全局变量(建立为响应式变量)
const user = reactive({ name: '333', authKeys: [] })
// 用户变量修改方法
const login = ( loginInfo ) => { user.name = loginInfo }

// 用户全局数据提供方法
export const userProvide = () => {
  // 提供一个只读的变量和修改方法
  provide( UserSymbol, {user: readonly(user), login} )
}

// 用户全局数据注入方法
export const userInject = () => {
  return inject(UserSymbol)
}

在 src/context/index.js 对用户全局数据统一管理,因为我们未来还会有其他类型或者模块的数据。

// 导入用户模块全局数据
import { userProvide, userInject } from './data/user'
// 导出相关的注入方法
export { userInject }
// 导出相关的提供方法
export const contextProvider = () => {
    userProvide()
}

App.vue 作为根组件,依照概念我们在根组件中提供的数据,整个应用的其他组件都是子组件,自然可以自由访问数据。

// 导入全局上下文方法
import { contextProvider } from './context'
import HelloWorld from './components/HelloWorld.vue'
export default {
  name: 'App',
  setup() {
    // 根组件注册全局上下文
    contextProvider()
  },
  components: {
    HelloWorld
  }
}

HelloWorld 子组件中尝试读取数据。

<template>
  <div class="hello">
    <h1>以下为子组件</h1>
    <h1>{{ user.name }}</h1>
  </div>
</template>

<script>
import { userInject } from '/src/context'
export default {
  name: 'HelloWorld',
  setup() {
    const { user } = userInject()
    return { user }
  }
}
</script>

结果可以成功读取到 user.name 为 333,因此整个流程是畅通的,我们成功完成了【特性1全局访问】。

我们在子组件中导出了 user,上文我们说过为了确保可控的修改,导出的数据时只读的,我们编写一个方法尝试修改下。

<template>
  <div class="hello">
    <h1>以下为子组件</h1>
    <h1>{{ user.name }}</h1>
    <el-button type="primary" @click="setName()">我来修改</el-button>
  </div>
</template>

编写一个方法 setName() 如下:

  methods:
  {
    setName() {
        // user 是只读的,理论上我们无法修改
        this.user.name = Math.ceil(Math.random()*1000) + ''
    }
  }

尝试修改,确实无法修改,报错如下:

image-20210715152820075

回顾我们在定义全局数据时,不仅导出了数据,同时暴露一个修改方法,这个方法就是用于修改数据的。

因此我们修改子组件 HelloWorld.vue 如下:

<template>
  <div class="hello">
    <h1>以下为子组件</h1>
    <h1>{{ user.name }}</h1>
    <el-button type="primary" @click="setName()">我来修改</el-button>
  </div>
</template>

<script>
import { userInject } from '/src/context'
export default {
  name: 'HelloWorld',
  setup() {
    // 注入修改方法
    const { user, login } = userInject()
    return { user, login }
  },
  methods:
  {
    setName() {
      // 调用提供的修改方法
      this.login(Math.ceil(Math.random()*1000) + '')
    }
  }
}
</script>

image-20210715153245800

自此,我们完成了【特性2全局更新】【特新3可控修改】。

通过上方的样例,我们基本可以确认,Vue3 自身就能够实现全局状态管理,可以尝试用来替代 Vuex 吧。

米虫

做一个有理想的米虫,伪全栈程序猿,乐观主义者,坚信一切都是最好的安排!

本站由个人原创、收集或整理,如涉及侵权请联系删除

本站内容支持转发,希望贵方携带转载信息和原文链接

本站具有时效性,不提供有效、可用和准确等相关保证

本站不提供免费技术支持,暂不推荐您使用案例商业化

发表观点

提示

昵称

邮箱

QQ

网址

当前还没有观点发布,欢迎您留下足迹!

同类其他

WEB

CSS文字超出隐藏添加省略号及失效处理

在前端页面中文字超出隐藏并添加省略号是比较常见的样式处理,实际CSS样式中单行省略和多行省略的样式有所差异,在某些特殊场景下多行超出的样式会不生效,本文给出相关解决方案

CSS3通过Gradients实现渐变背景色

使用背景色渐变可以使得页面质感得到大幅度提升,CSS样式中通过gradients属性指定两个或多个颜色之间平滑过渡,由于颜色的渐变是由浏览器生成,因此不会出现不同分辨率下失真的情况。

侧边栏下滑即将越过时动态固顶与上滑恢复

对于很多二栏布局的网站而言,正文部分过长时,侧边栏区域下拉过程中出现大片空白,因此我们可以实现当屏幕下滑达到指定元素位置(如即将越过)后对元素固顶来解决侧边栏区域的空旷感

Jquery.bind()实现前端字段公共校验器

严谨的页面开发需要着重关注前台校验相关的内容,确保请求参数的合法以保证服务器安全,界面参数众多需要建立一个公共方法,公共校验器的核心方法是Jquery.bind()

Jquery+CSS轻松实现导航动态显示隐藏

绝大多数网站都会有个顶部导航,对于手机端而言为了便于访问导航常常会做固顶操作,通过CSS样式配合Jquery的scroll()方法或原生JS监听滑动事件方法,可以轻松实现下滑隐藏,上滑显示的效果

前端多终端自适应网页开发模式

智能移动终端大爆发的现阶段,手机访问网页已经成为人们不可或缺的使用习惯,开发自适应网页大势所趋,实际上无论改造还是开发本身并不复杂,但是掌握更好的开发模式会使得你编写页面更加高效快捷

选择个人头像

昵称

邮箱

QQ

网址

评论提示

  • 头像:系统为您提供了12个头像自由选择,初次打开随机为你选择一个
  • 邮箱:可选提交邮箱,该信息不会外泄,或将上线管理员回复邮件通知
  • 网址:可选提交网址,评论区该地址将以外链的形式展示在您的昵称上
  • 记忆:浏览器将记忆您已选择或填写过得信息,下次评论无需重复输入
  • 审核:提供一个和谐友善的评论环境,本站所有评论需要经过人工审核