使用vuex实现登录注册功能及&auth模块
大纲链接 §
[toc]
vuex
为什么用 vuex
- 当项目的许多不同层级组件都需要用到数据和传递数据,即 多个组件共享状态
- 单级数据传递方式
props/emits、祖孙通信project/inject或者中央总线eventBus满足不了这样复杂的数据传递方式的同时又要保证代码逻辑简洁清晰 - 因此抽象出一个统一状态管理的对象,以一个 全局单例模式管理,保证状态变化可预测,并保 单向数据流的简洁性
vuex 使用详解
由于使用
Composition API代替OptionalAPI,所以mapState、mapGetters等映射方法不再使用
vuex 使用 TypeScript 支持
声明 Vue 的自定义类型
ComponentCustomProperties@/types/vuex.d.ts
|
|
使用
useStore()组合式函数类型声明
- 希望
useStore返回类型化的store,必须执行以下步骤:
- 定义类型化的
InjectionKey, 定义export const key: InjectionKey<Store<State>> = Symbol(); - 将
store安装到Vue应用时,提供该类型化的InjectionKey,挂载app.use(store, key); - 将类型化的
InjectionKey传给useStore方法 ,
@/store/index.ts使用 Vue 的InjectionKey接口和自己的 store 类型定义来定义 key
|
|
main.ts将store安装到 Vue 应用时传入定义好的injection key
|
|
- 在
main.ts里面先挂载好vuex, 再挂路由 - 否则在导航守卫中
router.beforeEach中使用会提示vuex还未安装
使用时,将上述
injection key传入useStore方法可以获取类型化的store
|
|
- Vuex 将store 安装到 Vue 应用中使用了 Vue 的 Provide/Inject 特性
简化 useStore 用法
- 每次使用
useStore,都需引入InjectionKey并将其传入useStore到使用过的任何地方,重复冗余 - 定义自己的组合式函数来检索类型化的
store
@/store/index.ts
|
|
通过引入自定义的组合式函数,不用提供
injection key和类型声明就可以直接得到类型化的store
|
|
- 通过调用
useStore函数,在setup钩子函数中访问store - 这与在组件中使用选项式 API 访问
this.$store是等效的
使用组合式API 访问 State 和 Getter
- 组件中,为了访问
state和getter,需要创建computed引用,来 保留响应性 - 这与在选项式 API 中创建计算属性等效
- 官方文档 访问 State 和 Getter
|
|
- 保留响应性
const count = computed(() => (store.state.count))onst double = computed(() => (store.getters.double)
使用组合式API 访问 Mutation 和 Action
- 要使用
mutation和action时,只需要在setup钩子函数中调用commit和dispatch函数
|
|
- 状态变更
const increment = () => store.commit('increment')const asyncIncrement = () => store.dispatch('asyncIncrement')
Vuex + TS添加Module的类型
实现
Vuex4 typescript中自动将modules的类型添加到state中
- 在
vuex4中使用typescript定义类型模块modules时,如果不做一些处理,在使用Hooks获取store然后取子模块的state会丢失类型
|
|
- state类型定义单独放在一个文件中处理,方便管理
- 各个子模块的类型定义,单独放在子模块的文件夹中处理,最后统一在根节点上
- 如果有很多公用的类型可以抽取出来
参考
- Vuex4 typescript 中自动将modules的类型添加到state中
- vuex4.0中使用typescript, vuex4.0中modules的ts使用,vue3 + vuex4.0 + typescript 使用详情
vuex在项目中的目录结构
|
|
定义 root 顶层 state 的数据类型, 在
@/store/interface.ts中
|
|
Store入口index.ts
|
|
vuex在项目中的使用 auth 模块
@/store/modules/auth/interface声明类型
|
|
const TestModule: Module<TestModulesTypes, RootStateTypes>ActionContext<AuthModuleTypes, RootStateTypes>;
@/store/modules/auth/authStore.ts
|
|
- 第一个泛型参数为当前子模块
AuthModuleTypes的 state 类型定义 - 第二个参数为根级 state 的类型定义
RootStateTypes - 只要定义了 state 的类型,在所有使用state的地方均会自动推断,不需要再定义
@/store/modules/auth/index
|
|
BlogModule模块
@/store/modules/blog/
|
|
@/store/modules/blog/
|
|
@/store/modules/blog/
|
|
登录注册的功能实现
@/pages/login/Login.vue登录
|
|
- 调用
store.dispatch('login', logString);
@/pages/register/Register.vue注册
|
|
vuex只能在使用 state 时,能够享受到TS的完全加持,但是却不能很好地对 mutation , action 以及 getter 进行很友好的类型检查
改用 Pinia 代替Vuex 操作状态管理
Vuex 没有为 this.$store 属性提供开箱即用的TypeScript 类型声明
初始化 pinia
- 通过
createPinia初始化 Pinia,并将其挂载到 Vue 的实例上
src/main.ts
|
|
创建
src/store/index.ts文件,用于存放store
|
|
defineStore()的第一个参数用于设置store的容器名称,该名称必须唯一,不可重复!
store的目录结构
|
|
@/store/modules/auth/authStore
|
|
@/store/modules/auth/interface
|
|
@/store/modules/auth/index
|
|
pinia 遇坑
- 报错
Uncaught Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia? - 在
router中使用的例子,必须在钩子函数中声明const store = useStore(),而不是在钩子外 - Pinia官网示例
- Pinia官网示例 Using a store outside of a component
- Pinia官网示例 Using the store outside of setup()
- github issue #666 I can’t use pinia outside of component setup
- stackoverflow Vue: Can’t access Pinia Store in beforeEnter vue-router
|
|
https://juejin.cn/post/7057950109832577054?utm_source=gold_browser_extension | Pinia初体验 - 掘金 https://juejin.cn/post/7036745610954801166#heading-33 | Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架【值得收藏】 - 掘金 https://juejin.cn/post/7057439040911441957 | Pinia进阶:优雅的setup(函数式)写法+封装到你的企业项目 - 掘金 https://juejin.cn/post/7056894606650114085#heading-3 | Vue3.2+Vite+TS+pinia+router4搭建 - 掘金 http://localhost:3000/#/create https://pinia.vuejs.org/getting-started.html | Installation | Pinia https://stackblitz.com/github/piniajs/example-vue-3-vite?file=src%2Fcomponents%2FPiniaLogo.vue | Piniajs - Example Vue 3 Vite - StackBlitz https://pinia.vuejs.org/introduction.html#comparison-with-vuex | Introduction | Pinia https://juejin.cn/post/6986847203885056036 | Pinia 快速入门 - 掘金 https://juejin.cn/post/6977648886869393444 | Pinia,替代Vue.js的容器 - 掘金 https://segmentfault.com/a/1190000041246156 | 新一代状态管理工具,Pinia.js 上手指南 - SegmentFault 思否 http://jspang.com/detailed?id=82 | 技术胖-Pinia入门视频教程 全新一代状态管理工具Pinia -Vue3全家桶系列 https://jishuin.proginn.com/p/763bfbd61629 | Pinia是Vuex的良好替代品吗?-技术圈 https://zhuanlan.zhihu.com/p/413389658 | Vuex4 对 TypeScript 并不友好,所以我选择 Pinia - 知乎 https://juejin.cn/post/7041188884864040991 | vite + vue3 + setup + pinia + ts 项目实战 - 掘金
参考文章
相关文章
- 无
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名