概述
Vue3+TypeScript基于provide/inject封装store替代Vuex
关键词
- Vue3
- provide/inject
- reactive
先看看Vue3的官方文档是如何介绍inject/provide的
通常,当我们需要将数据从父组件传递到子组件时,我们使用 props。想象一下这样的结构:你有一些深嵌套的组件,而你只需要来自深嵌套子组件中父组件的某些内容。在这种情况下,你仍然需要将 prop 传递到整个组件链中,这可能会很烦人。
对于这种情况,我们可以使用 provide 和 inject 对。父组件可以作为其所有子组件的依赖项提供程序,而不管组件层次结构有多深。这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这个数据。
其实说白了就是依赖注入,在Vue2里面我们如果要在关系比较复杂的组件之间共享状态,一般都需要采用Vuex这种方案,但是这样就引入了新的学习成本,要去理解各种State、Mutations、Module等等。
废话少说,下面开始说说我是如何封装一个Store的。
src/store/index.ts
// src/store/index.ts
import { App, watch } from "vue";
import UserStore from "./UserStore";
/**
* IStore接口,所有Store都必须实现这个接口才能注册
*/
declare interface IStore<State> {
/**
* 是否开启持久化
*/
persistedState: boolean;
/**
* State
*/
state: State;
}
/**
* 待注册的store,类似于vuex中的module
*/
const Stores: Record<string, IStore<any>> = { UserStore };
/**
* 用于安装vue插件的方法,需要在main.ts里导入并调用app.use()才可以集成store
* @param app Vue实例
*/
const store = (app: App) => {
// 遍历所有Store
const keys = Stores && Object.keys(Stores);
keys &&
keys.forEach((item: string) => {
// 注入
app.provide(item, Stores[item].state);
// 持久化处理
if (Stores[item].persistedState) {
// 读取sessionStorage的值
const storageState = JSON.parse(sessionStorage.getItem(item) || "{}");
for (const key in storageState) {
Stores[item].state[key] = storageState[key];
}
// 监听值变化,保存到sessionStorage
watch(
() => Stores[item].state,
() => {
sessionStorage.setItem(item, JSON.stringify(Stores[item].state));
},
{ deep: true }
);
}
});
};
export default store;
export { IStore };
src/store/UserStore.ts
// src/store/UserStore.ts
import { reactive } from "vue";
import { IStore } from "@/store";
/**
* IUserState
*/
declare interface IUserState {
/**
* 令牌
*/
token: string;
/**
* 用户名
*/
username: string;
/**
* 昵称
*/
nickname: string;
/**
* 用户id
*/
id: number;
/**
* 用户性别
*/
gender: number;
}
// 使用Vue3提供的reactive方法,将一个普通对象包装成响应式的
const state: IUserState = reactive({
token: "",
username: "",
nickname: "",
id: 0,
gender: 0,
});
const store: IStore<IUserState> = {
persistedState: true,
state: state,
};
export default store;
export { state, IUserState };
src/main.ts
// src/main.ts
import { createApp } from "vue";
import App from "./App.vue";
import store from "./store";
createApp(App).use(store).mount("#app");
至此,store的封装与集成就已经完成,并且在集成时会自动将各个IStore的State注入到App实例中,后续可以在组件的inject
选项里声明需要的State,或者在setup()
里使用inject()
方法获取需要的State。
最后
以上就是称心柜子为你收集整理的Vue3+TypeScript基于provide/inject封装store替代VuexVue3+TypeScript基于provide/inject封装store替代Vuex的全部内容,希望文章能够帮你解决Vue3+TypeScript基于provide/inject封装store替代VuexVue3+TypeScript基于provide/inject封装store替代Vuex所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复