vue2升级vue3:vue3真的需要vuex或者Pinia吗?hooks全有了

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

在写 《vue2升级vue3TypeScript下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同样有效。具体参看
Vue3你还在用Vuex一个“函数式”状态管理的新思路 https://zhuanlan.zhihu.com/p/345963989
Vue3 尝鲜 Hook + TypeScript 取代 Vuex 实现图书管理小型应用 https://my.oschina.net/sl1673495/blog/4439246 全局注入

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升级vue3vue3真的需要vuex或者Pinia吗hooks全有了》,

请注明出处https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8881.html

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: vue