在写 《vue2升级vue3:TypeScript下vuex-module-decorators/vuex-class to vuex4.x》,建议新项目使用 Pinia,但是我的项目部分组件希望直接打包出去给地方使用。这个时候还是会遇到vue2 是否打包出vuex的 问题。所以,干脆舍弃 vuex/Pinia,直接使用 vue3 原生搞定——hook出现之后,状态管理的问题已经从根本上被消解了!

vue-composition 提供了类似 React Hook 的能力,将 Vue 的抽象层级从「组件级(Component)」降低为「函数级(Function)」。

当掌握了Hook(或者Composition API)之后,感觉万物皆可hook,总是想把数据和操作这堆数据的方法封装在一起!

1、方案有以下几种reactive 响应式数据取代store,在各个组件hooks 调用

const store = reactive({state: {})

2、利用rovide和inject,类似react  context,做全局数据管理(不推荐)具体可参看:《vue2升级vue3:provide与inject 使用注意事项

父组件

const person = reactive({name: 'bob', age:32});
provide('person', person);

子组件

const person = inject('person');

有了provide/inject和ref/reactive配合,父子组件/兄弟组件共享状态的问题已经迎刃而解。

通过provide提供了一个reactive响应式对象;然后在子组件通过inject注入该对象。在子组件修改对象的age属性,视图就会响应式更新!同样的,如果child组件也有自己的子组件,调用inject同样有效。具体参看:

1、2方法结合:

hooks

export function useUserInfo() {
  const userInfo = reactive({ });
  
  const login = (data) => {...};
  const logout = () => {...};
  const editUserInfo => (data) => {};
  
  return {
   userInfo,
   login,
   logout,
   editUserInfo
  }
}

在根组件调用provide,将userHook函数传入

import {useUserInfo} from '@/hooks/userUserInfo';
provide('user', useUserInfo())

这个 封装好的东西,直接看这个:https://github.com/tbhuabi/vue-di-plugin

但是还是不推荐这个写法!即使 provide/inject 再香,我还是绕道走,总感觉 这玩意和react的 useContext + useReducer 貌似 貌合神离——可以看一下  :https://github.com/tangxiangmin/vue3-hook/tree/master/src/useReducer

1、使用

比如我之前的数据,vuex的

/**
 * 面板查询变量
 */ import { VuexModule, Module, getModule, Mutation } from 'vuex-module-decorators';
import store from '../index';
import { TimeRangeType } from '@/components/time-range';
import { DEFAULT_TIME_RANGE, TimeRange } from '@/components/time-range/utils';
import { FiltersList, FilterType, QueryContextState } from '@/typings'; @Module({ dynamic: true, store, name: 'queryContext' })
export default class QueryContext extends VuexModule implements QueryContextState {
  timeRange: TimeRangeType = DEFAULT_TIME_RANGE;
  timezone = 'Asia/Shanghai';
  variables: FiltersList = {};
  share_uid = '';
  // 缓存的时间 - TimeRangeType 转时间戳
  get getTimeRange(): [number | string, number | string] {
    const date = new TimeRange(this.timeRange);
    const [start, last] = date.value;
    return [start.valueOf(), last.valueOf()];
  }
  @Mutation
  setTimeRange(range: TimeRangeType) {
    this.timeRange = range;
  }
  @Mutation
  setTimezone(zone: string) {
    this.timezone = zone;
  }
  @Mutation
  setShareUid(share_uid: string) {
    this.share_uid = share_uid;
  }
  @Mutation
  setVariation({ name, value }: { name: string; value: FilterType }) {
    // this.variables[name] = value;
    this.variables = { ...this.variables, [name]: value };
  }   @Mutation
  setVariations(variables: FiltersList) {
    this.variables = variables;
  }
  @Mutation
  clear() {
    this.variables = {};
    this.timeRange = DEFAULT_TIME_RANGE;
  }
} export const QueryContextModule = getModule(QueryContext);

直接使用响应式数据

import { reactive } from 'vue';
import { FiltersList, FilterType, QueryContextState } from '@/typings';
import { DEFAULT_TIME_RANGE } from '@/components/time-range/utils';
import { TimeRangeType } from '@/components/time-range';
export const QueryContextModule = reactive<QueryContextState>({
  timeRange: DEFAULT_TIME_RANGE,
  timezone: 'Asia/Shanghai',
  variables: {},
  share_uid: '',
});
export function setTimeRange(range: TimeRangeType) {
  QueryContextModule.timeRange = range;
}
export function setTimezone(zone: string) {
  QueryContextModule.timezone = zone;
}
export function setShareUid(share_uid: string) {
  QueryContextModule.share_uid = share_uid;
}
export function setVariation({ name, value }: { name: string; value: FilterType }) {
  QueryContextModule.variables = { ...QueryContextModule.variables, [name]: value };
}
export function setVariations(variables: FiltersList) {
  QueryContextModule.variables = variables;
}
export function clear() {
  QueryContextModule.variables = {};
  QueryContextModule.timeRange = DEFAULT_TIME_RANGE;
}

改为类vuex,可以参看此篇文章: Vue3 还要啥 Vuex,自定义 hooks给你实现数据共享和状态管理 https://juejin.cn/post/7054060160045547550

import { reactive } from 'vue';
import { FiltersList, FilterType } from '@/typings';
import { DEFAULT_TIME_RANGE } from '@/components/time-range/utils';
import { TimeRangeType } from '@/components/time-range';
const store = reactive({
  state: {
    timeRange: DEFAULT_TIME_RANGE,
    timezone: 'Asia/Shanghai',
    variables: {},
    share_uid: '',
  },
}); export function setTimeRange(range: TimeRangeType) {
  store.state.timeRange = range;
}
export function setTimezone(zone: string) {
  store.state.timezone = zone;
}
export function setShareUid(share_uid: string) {
  store.state.share_uid = share_uid;
}
export function setVariation({ name, value }: { name: string; value: FilterType }) {
  store.state.variables = { ...store.state.variables, [name]: value };
}
export function setVariations(variables: FiltersList) {
  store.state.variables = variables;
}
export function clear() {
  store.state.variables = {};
  store.state.timeRange = DEFAULT_TIME_RANGE;
} export const useQueryContext = () => ({
  store,
  setTimeRange,
  setTimezone,
  setShareUid,
  setVariation,
  setVariations,
  clear,
});

这个使用肯定是还太粗糙,项目中使用的代码,等有空的 脱密了在分享一下

参考文章:

有了 Vue3 还要啥 Vuex,自定义 hooks给你实现数据共享和状态管理 https://juejin.cn/post/7054060160045547550

转载本站文章《vue2升级vue3:vue3真的需要vuex或者Pinia吗?hooks全有了》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8881.html

vue2升级vue3:vue3真的需要vuex或者Pinia吗?hooks全有了的更多相关文章

  1. uniapp项目vue2升级vue3简单记录

    看到好多开源项目都升级了vue3,看文章说vue3性能升级很多,而且组合式api很香,遂把最近开发的自助洗车app升级下,在此记录下出现的问题. uniapp升级vue3官方指南 我是先去vue官网看 ...

  2. vue2升级vue3:vue2 vue-i18n 升级到vue3搭配VueI18n v9

    项目从vue2 升级vue3,VueI18n需要做适当的调整.主要是Vue I18n v8.x 到Vue I18n v9 or later 的变化,其中初始化: 具体可以参看:https://vue- ...

  3. vue2升级vue3指南(二)—— 语法warning&error篇

    本文总结了vue2升级vue3可能会遇到的语法警告和错误,如果想知道怎样升级,可以查看我的上一篇文章:vue2升级vue3指南(一)-- 环境准备和构建篇 Warning 1.deep /deep/和 ...

  4. vue2升级vue3:Vue Demij打通vue2与vue3壁垒,构建通用组件

    如果你的vue2代码之前是使用vue-class-component 类组件模式写的.选择可以使用 https://github.com/facing-dev/vue-facing-decorator ...

  5. vue2升级vue3:vue-i18n国际化异步按需加载

    vue2异步加载之前说过,vue3还是之前的方法,只是把 i18n.setLocaleMessage改为i18n.global.setLocaleMessage 但是本文还是详细说一遍: 为什么需要异 ...

  6. 基 vue-element-admin升级的Vue3 +TS +Element-Plus 版本的后端管理前端解决方案 vue3-element-admin 正式对外发布,有来开源组织又一精心力作,毫无保留开放从0到1构建过程

    项目简介 vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 + Element Plus 版本的后台管理前端解决方案,是 有来技术团队 继 youla ...

  7. 简单对比vue2.x与vue3.x响应式及新功能

    简单对比vue2.x与vue3.x响应式 对响应方式来讲:Vue3.x 将使用Proxy ,取代Vue2.x 版本的 Object.defineProperty. 为何要将Object.defineP ...

  8. vue2.0 与 vue3.0 配置的区别

    提示:要了解vue2.0与vue3.0区别,首先你要熟悉vue2.0 从最明显最简单的开始 项目目录结构 可以明显的看出来,vue2.0与3.0在目录结构方面,有明显的不同(vue3.0我是安装了cs ...

  9. 在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下。

    在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下. vue2.0 中的使用方法 父组件: <template> <d ...

  10. 结合 Vuex 和 Pinia 做一个适合自己的状态管理 nf-state

    一开始学习了一下 Vuex,感觉比较冗余,就自己做了一个轻量级的状态管理. 后来又学习了 Pinia,于是参考 Pinia 改进了一下自己的状态管理. 结合 Vuex 和 Pinia, 保留需要的功能 ...

随机推荐

  1. kubeadm 添加master及node

    1.添加master 新master服务器初始化 添加k8s源 $ cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] ...

  2. [C++]P5024 树形DP 保卫王国

    树形DP 保卫王国P5024 前置知识 1.邻接表 + Dfs(深度优先搜索) 2.基础DP(如 01背包 ) 3.最小公共祖先(LCA) LCA我有写过Blog 首先解读一下题意 城市即为节点 每个 ...

  3. Java 面试题之 Logback 打印日志是如何获取当前方法名称的?

    在 Java 中,有四种方法可以获取当前正在执行方法体的方法名称,分别是: 使用 Thread.currentThread().getStackTrace() 方法 使用异常对象的 getStackT ...

  4. 快速入门:构建您的第一个 .NET Aspire 应用程序

    前言 云原生应用程序通常需要连接到各种服务,例如数据库.存储和缓存解决方案.消息传递提供商或其他 Web 服务..NET Aspire 旨在简化这些类型服务之间的连接和配置.在本快速入门中,您将了解如 ...

  5. 动态规划——提高Ⅴ(DP优化)

    单调队列优化DP 其实单调队列就是一种队列内的元素有单调性(单调递增或者单调递减)的队列,答案(也就是最优解)就存在队首,而队尾则是最后进队的元素.因为其单调性所以经常会被用来维护区间最值或者降低DP ...

  6. DOS(Terminal)常用命令

    DOS是一款在20世纪末期流行的操作系统,它是一款面向磁盘的系统软件.它的用途非常广泛,大名鼎鼎的 Windows 98 就是基于它的.DOS依然活跃,比如FreeDOS. cmd是指命令行提示符,是 ...

  7. Walrus 0.4发布:单一配置、多态运行,体验下一代应用交付模型

    今天,我们高兴地宣布云原生统一应用平台 Walrus 0.4 正式发布,这是一个里程碑式的版本更新.新版本采用了全新的应用模型--仅需进行单一配置,即可在多种模态的基础设施及环境中运行包括应用服务及周 ...

  8. 【Javaweb】动态web工程目录介绍

    src 存放自己编写的Java源代码 web 专门用来存放web工程的资源文件(html页面.css文件.js文件等等) WEB-INF 是一个受服务器保护的目录,浏览器无法直接访问此目录的内容 we ...

  9. Serializable是什么?为什么在Entity层要实现Serializable接口

    我在做房产信息管理系统时用到了Serializable接口 Serializable含义: 一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化. Serializ ...

  10. mysql alter与update的区别

    alter是更改表名,字段的 而updata是更改数据的,一定要记住要联合where使用,否则就会全部更改. updata与set联用 alter与change column和add联用