Vue3 项目实战 Pinan状态管理多语言
8.1 安装依赖
# 1 安装 pinia 依赖
npm install pinia@next
# 2 安装 pinia 持久化依赖
npm install pinia-plugin-persistedstate
8.2 封装pinia
// /src/stores/index.js
import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate'
// 创建 pinia 实例
const pinia = createPinia()
// 注册 持久化插件
pinia.use(persist)
// 导出 pinia
export default pinia
8.3 全局注册
import { createApp } from 'vue'
import App from './App.vue'
// 引入模版的全局样式
import '@/styles/main.scss'
import pinia from './stores'
const app = createApp(App)
app.use(pinia)
app.mount('#app')
8.4 封装 Store
// stores/language.js
import { defineStore } from 'pinia'
import { readonly } from 'vue'
import { ref } from 'vue'
export const useLanguageStore = defineStore('language', () => {
// 1 支持的语言列表(可根据需要扩展)
const supportedLanguages = ['zh', 'en', 'es']
// 2 初始化语言(从浏览器语言检测)
function initLanguage() {
// 1 获取浏览器默认语言
const browserLang = navigator.language?.toLowerCase().split('-')[0]
// 2 获取本地存储语言
const storyData = localStorage.getItem('app-language')
const localStoryLanguage = storyData ? JSON.parse(storyData).language : null;
// 3 返回结果
const res = localStoryLanguage || browserLang || 'zh'
return res
}
// 3 当前语言
const language = ref(initLanguage())
// 4 设置语言
function setLanguage(lang) {
if (supportedLanguages.includes(lang)) {
language.value = lang
return true
}
return false
}
return {
language: readonly(language),
setLanguage
}
}, {
persist: {
key: 'app-language', // 自定义存储键名
storage: localStorage, // 明确使用 localStorage(默认值)
}
})
8.5 Vue组件内适用
<script>
import { useLanguageStore } from "@/src/stores/language.js"
const languageStore = useLanguageStore()
// 1 直接适用状态
languageStore.language
// 2 设置状态
languageStore.setLanguage(lang)
</script>
8.6 vue组件之外的调用
注意:外部调用 不在vue组件控制范围,会导致在同步本地数据之前取的初始值!!需要手动刷新浏览器才更新!!!
// 普通的js文件调用 pinia 的状态,会报错' 使用之前没有创建 pinia ',解决办法如下:
import { createI18n } from "vue-i18n"
import { useLanguageStore } from "@/stores/modules/useLanguageStore.js"
import zh from "./language/zh.js"
import en from "./language/en.js"
import es from "./language/es.js"
const messages = {
zh: zh,
en: en,
es: es,
}
// vue模块 之外的调用方法
import { createPinia } from "pinia"
const pinia = createPinia()
const languageStore = useLanguageStore(pinia)
console.log("---- i18n.js ---" + languageStore.lang)
const i18n = createI18n({
// 使用状态
locale: languageStore.lang,
fallbackLocale: 'en',
messages: messages,
})