Pinia
官网:https://pinia.vuejs.org/zh/
Pinia 是 Vue 的专属状态管理库,相比Vuex更好用,优点不多了说官网有,用起来最重要!
在应用的根部注入创建的 pinia
// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
定义store,拿用户登录举个简单例子
在src目录新建文件夹store,然后新建文件user.ts
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { login } from '~/api/user'
import { UserInfo } from '~/types/index'
// 此处采用组合式API写法
// Pinia 同样支持选项式API写法
export const useUserStore = defineStore(
'user',
() => {
let username = ref('')
async function userLogin(param: UserInfo) {
const result = await login({ username: param.username, password: param.password })
if (result) {
username.value = param.username
}
return result
}
return { username, userLogin }
}
)
在Vue页面中使用Pinia
import { useUserStore } from '~/store/user'
...
const userStore = useUserStore()
const submitForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.validate(async (valid: boolean) => {
if (valid) {
const result = await userStore.userLogin(param)
if (result) {
router.push('/')
}
}
})
}
...
持久化插件pinia-plugin-persistedstate
如果我们把登录用户的信息放在Pinia中,那肯定需要做持久化,要不页面一刷新,用户信息就没有了。
比较粗暴的做法就是直接使用localStorage/sessionStorage来保存用户信息(连Pinia都不用),进阶做法是当Pinia保存后再给localStorage保存一份,退出登录时同时清理这两处的数据。
更加优雅的做法应该是使用轮子,让代码更干净可配置,来试试持久化插件吧,大家比较推荐的是pinia-plugin-persistedstate,更稳定更少bug。
安装 pinia-plugin-persistedstate
npm i pinia-plugin-persistedstate
修改配置
//main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' // 新增
import App from './App.vue'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) // 新增
const app = createApp(App)
app.use(pinia)
app.mount('#app')
// store/user.ts
export const useUserStore = defineStore(
'user',
() => {
let username = ref('')
...
return { username, userLogin }
},
// 新增
{
persist: true
}
)
这时再点击登录,localstorage就会新增user了 👍
如果想给key值改名
persist: { key: 'my-custom-key', },
如果你想把数据保存在sessioinStorage中,可以配置persist
persist: { storage: sessionStorage, },
给Tags页签组件增加持久化
本项目的页签组件Tags本来也没有做持久化,刷新页面时tag会丢失其他已打开的页面,引入pinia-plugin-persistedstate 之后,只用在store/tags.ts 加入persist配置就好了。
persist: {
storage: sessionStorage
},
更多的配置请参考官方文档:https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/config.html
踩坑
按照官方文档配完应该就可以按F12在localStorage中看到我刚才写的user,然而又掉坑了,坑虽不大,记录下也是应该的。
因为疏于使用pinia,所以在写store/user.ts的时候,直接照着官网文档又来了一遍createPinia,然后把persistedstate插件挂在它身上,结果localStorage怎么也不出来。
🌹 正确的做法是在main.ts挂载pinia的时候,把persistedstate插件挂上去,别的store文件就不要再createPinia了,一切OK!
小tips
还有一点需要注意,在使用组合式API写法时,state定义需要使用ref,否则也会拿不到数据,所以千万别写成:
let username = ref('') // 正确
let username = '' // 错误
在 Setup Store 中:
ref()
就是state
属性computed()
就是getters
function()
就是actions
如果使用选项式API,就不用操心这个。养成习惯就好哈~
本项目GIT地址:github.com/lucidity99/…