pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。就是和vuex一样的实现数据共享。
依据Pinia官方文档,Pinia是2019年由vue.js官方成员重新设计的新一代状态管理器,更替Vuex4成为Vuex5。
Pinia 目前也已经是 vue 官方正式的状态库。适用于 vue2 和 vue3。可以简单的理解成 Pinia 就是 Vuex5。也就是说, Vue3 项目,建议使用Pinia。
pinia的优点
npm install pinia
//引入stores暴露出的pinia的实例
import { createPinia } from 'pinia'
createApp(App).use(createPinia()).use(router).mount('#app')

import { defineStore } from 'pinia'
interface FeatureManageType {
isIframeParent: boolean
}
export const useFeatureStore = defineStore('featureInfo', {
state: () => ({
featureInfo: {} as FeatureManageType,
}),
actions: {
getFeatureInfo(params: FeatureManageType) {
console.log('--pinia---params--', params)
this.featureInfo = params
},
},
})
import { useFeatureStore } from '@/stores'
// 初始化定义值
const iframeParentInfo = ref({ isIframeParent: true })
// 获取和操作 featureStore 中的状态
const featureStore = useFeatureStore()
const messageHandler = (e) => {
// 通过origin对消息进行过滤,避免遭到XSS攻击
if (e.origin !== 'http://127.0.0.1:8080') {
parseData({})
return
}
if (typeof e.data === 'string') {
parseData(e.data)
}
}
const parseData = (data) => {
try {
iframeParentInfo.value = JSON.parse(data)
console.log('父页面传输过来参数', data)
} catch (error) {
// console.log('解析JSON出错', error)
iframeParentInfo.value = { isIframeParent: false }
}
// 存储数据
featureStore.getFeatureInfo(iframeParentInfo.value)
}
onMounted(() => {
// 获取 父向 子(iframe) 传递的信息
window.addEventListener('message', messageHandler)
// 子(iframe)向父传递信息
window.parent.postMessage('Hello Parent!', '*')
})
import { useFeatureStore } from '@/stores'
const { featureInfo } = toRefs(useFeatureStore().$state)
console.log('获取到存储featureInfo的值', featureInfo)
可以参考链接 Vue 3 & Pinia 状态管理(3) - Pinia State 的相关使用
在 Vue3 中,如果你使用 window.open 打开新的页面,那么新的页面将会是一个全新的环境,它无法访问到原页面的内存数据,包括 Pinia 存储的数据。
如果你需要在新页面中使用到某些数据,你可以:
let routeUrl = $router.resolve({
path: '/featureInfo',
query: {
...formDraftInfo,
featureId: String(id),
featureVersionId: String(versionId),
type: 'add',
},
})
window.open(routeUrl.href, '_blank')
localStorage.setItem('data', JSON.stringify(data))
// 在新页面中
let data = JSON.parse(localStorage.getItem('data'))
请注意,以上两种方式都无法直接使用 Pinia 存储的数据,因为 Pinia 存储的数据只存在于原页面的内存中。