15-Pinia实现store状态管理

Vite2+Vue3+TypeScript+Element-plus脚手架搭建系列

✅01-初始化 Vite 项目
✅02-配置 Vite2 环境变量
✅03-Vite2 配置及说明
✅04-Vue3 使用 SCSS
✅05-Vue3 路由配置
✅06-TypeScript 配置及说明
✅07-Vue3 使用 axios
✅08-Vue3 axios 对象封装
✅09-ESLint 配置及说明
✅10-ESLint 与 Prettier 集成配置及说明
✅11-Mock.js 模拟接口数据
✅12-Vite2 引入 Element-Plus 框架
✅13-渐变+透明样式实现清爽登录页
✅14-Element-Plus 实现后台管理系统布局
✅15-Pinia 实现 store 状态管理
✅16-Vue3 动态路由权限控制


文章目录

  • Pinia 实现 store 状态管理
    • 目标
    • 功课
    • 准备
      • 安装依赖
      • 调整文件&目录
    • Coding
      • 创建并使用 Pinia
      • 用户信息 Store
      • 保存用户信息 store
      • Sidebar 读取 store 用户信息
      • Header 读取&重置 store 用户信息
    • 结果

源码地址:GitHub / 码云


Pinia 实现 store 状态管理

目标

用 Pinia 管理用户基本信息和菜单数据。登录成功后保存用户信息,并且可在 Header 和 Sidebar 读取用户信息。

功课

  • 什么是 Pinia ?
    Pinia 是一个用于 Vue 的状态管理库,类似 Vuex, 是 Vue 的另一种状态管理方案,Pinia 支持 Vue2 和 Vue3。官方文档

  • 什么是 Pinia Store ?
    Store是一个持有状态和业务逻辑的实体,它没有绑定到组件,它是全局的。它有点像一个组件,每个人都可以读取和写入。它有三个概念,state、getters 和 actions,可以假定这些概念等价于组件中的data, computed 和 methods。

准备

安装依赖

npm install -S pinia@next

调整文件&目录

src 目录下创建 store 文件夹,用来存放 store 模块文件。

store 文件目录结构如下:

src

---- store

-------- user-info.ts


Coding

只粘贴了部分核心代码,完整代码可去 GitHub / 码云 获取

创建并使用 Pinia

App.vue 创建一个 pinia 实例,并在 app 对象中注册使用:

import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router/index'
import 'element-plus/dist/index.css'
import '@/styles/index.scss'
import { useElementComponents } from '@/config/element'
import '@/mock/index'

/* ---------------------------- 导入 pinia 创建实例的函数 ---------------------------- */
import { createPinia } from 'pinia'

/* ----------------------------- 创建pinia实例并注册使用 ----------------------------- */
createApp(App).use(router).use(useElementComponents).use(createPinia()).mount('#app')

用户信息 Store

src/store/user-info.ts 中管理用户信息状态:

import { defineStore } from 'pinia'

// 定义用户信息Store
export const useUserInfoStore = defineStore('user-info', {
  state: () => ({
    id: 0,
    username: '',
    name: '',
    avatar: '',
    menus: [],
  }),
  actions: {
    setAll(userinfo: any) {
      this.id = userinfo.id
      this.username = userinfo.username
      this.name = userinfo.name
      this.avatar = userinfo.avatar
      this.menus = userinfo.menus
    },
  },
})

保存用户信息 store

修改 Login.vue 中登录逻辑,登录成功后保存用户信息:

......
const signin = () => {
  if (!form.username) {
    errorMessage('用户名为空')
  } else if (!form.password) {
    errorMessage('密码为空')
  } else {
    loginApi.signin(form).then((res: any) => {
      // ↓保存用户信息到store
      userInfoStore.setAll(res.data)
      router.push('/')
    })
  }
}
......

Sidebar 读取 store 用户信息

修改 src/components/ayout/sidebar/index.vue 将之前调用 API 获取用户信息改成从 store 获取:

......
import { defineComponent, inject, ref } from 'vue'
import { useUserInfoStore } from '@/store/user-info'

export default defineComponent({
  name: 'Sidebar',
  setup() {
    // ↓注入父组件值
    const sidebarCollapse = ref(inject('sidebarCollapse'))
    // ↓从store获取用户菜单
    const menus = useUserInfoStore().menus

    return {
      sidebarCollapse,
      menus,
    }
  },
})
......

Header 读取&重置 store 用户信息

修改 src/components/ayout/header/index.vue ,逻辑和 Sidebar 中相同。同时,在用户登出时重置 store :

......
setup(props, { emit }) {
  const router = useRouter()
  // ↓从store获取用户头像
  const avatar = useUserInfoStore().avatar

  // ↓Sidebar折叠/展开的开关
  const toggle = () => {
    // ↓修改父组件值
    emit('update:sidebarCollapse', !props.sidebarCollapse)
  }
  // ↓登出
  const signout = () => {
    // ↓将store重置为初始值
    useUserInfoStore().$reset()
    router.push('/login')
  }

  return { avatar, toggle, signout }
},
......

结果

  • 登录以后用户头像和菜单正常显示

本文为博主原创文章,任何个人、团体、机构转载和摘录,请注明出处。

你可能感兴趣的:(vue,elementui,typescript,前端,前端框架)