使用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
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名