createPinia()
创建一个可供应用程序使用的新 Pinia 实例。
签名
ts
function createPinia(): Pinia
返回值
一个具有以下属性和方法的新 Pinia 实例:
install
: Vue 插件安装函数use()
: 添加插件的方法state
: 包含所有 store 状态的响应式对象- 用于 store 管理的内部属性
基本用法
Vue 3
js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
Vue 2
js
import Vue from 'vue'
import { createPinia, PiniaVuePlugin } from 'pinia'
import App from './App.vue'
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
new Vue({
el: '#app',
pinia,
render: h => h(App)
})
配置
添加插件
可以添加插件来自定义 Pinia 行为:
js
import { createPinia } from 'pinia'
import { createPersistedState } from 'pinia-plugin-persistedstate'
const pinia = createPinia()
// 添加持久化插件
pinia.use(createPersistedState({
storage: sessionStorage,
key: id => `pinia-${id}`
}))
// 添加自定义插件
pinia.use(({ store }) => {
store.$router = router
store.$api = api
})
开发工具
js
import { createPinia } from 'pinia'
const pinia = createPinia()
// 在开发环境启用开发工具
if (process.env.NODE_ENV === 'development') {
pinia.use(({ store }) => {
store._customProperties = new Set(['$router', '$api'])
})
}
多个实例
你可以为应用程序的不同部分创建多个 Pinia 实例:
js
import { createPinia } from 'pinia'
// 主应用程序 pinia
const mainPinia = createPinia()
// 具有不同插件的管理面板 pinia
const adminPinia = createPinia()
adminPinia.use(adminPlugin)
// 使用不同的实例
app.use(mainPinia)
adminApp.use(adminPinia)
SSR(服务端渲染)
创建 SSR 兼容实例
js
// server.js
import { createPinia } from 'pinia'
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp({})
const pinia = createPinia()
app.use(pinia)
return { app, pinia }
}
状态序列化
js
// server.js
import { renderToString } from '@vue/server-renderer'
const { app, pinia } = createApp()
// 渲染应用
const html = await renderToString(app)
// 序列化状态
const state = JSON.stringify(pinia.state.value)
// 发送到客户端
const fullHtml = `
<div id="app">${html}</div>
<script>
window.__PINIA_STATE__ = ${state}
</script>
`
客户端水合
js
// client.js
import { createApp } from './main'
const { app, pinia } = createApp()
// 从服务器状态水合
if (typeof window !== 'undefined' && window.__PINIA_STATE__) {
pinia.state.value = window.__PINIA_STATE__
}
app.mount('#app')
测试
测试设置
js
import { createPinia, setActivePinia } from 'pinia'
import { beforeEach, describe, it } from 'vitest'
describe('Store 测试', () => {
beforeEach(() => {
// 为每个测试创建新的 pinia 实例
const pinia = createPinia()
setActivePinia(pinia)
})
it('应该工作', () => {
const store = useMyStore()
expect(store.count).toBe(0)
})
})
模拟插件
js
import { createPinia } from 'pinia'
import { vi } from 'vitest'
function createTestPinia() {
const pinia = createPinia()
// 模拟外部依赖
pinia.use(() => ({
$api: {
get: vi.fn(),
post: vi.fn()
},
$router: {
push: vi.fn(),
replace: vi.fn()
}
}))
return pinia
}
高级配置
自定义状态序列化
js
import { createPinia } from 'pinia'
import { ref } from 'vue'
function createCustomPinia() {
const pinia = createPinia()
// 复杂类型的自定义序列化
pinia.use(({ store }) => {
store.$serialize = () => {
const state = { ...store.$state }
// 自定义序列化逻辑
if (state.date instanceof Date) {
state.date = state.date.toISOString()
}
return state
}
store.$deserialize = (data) => {
// 自定义反序列化逻辑
if (typeof data.date === 'string') {
data.date = new Date(data.date)
}
store.$patch(data)
}
})
return pinia
}
性能监控
js
import { createPinia } from 'pinia'
function createMonitoredPinia() {
const pinia = createPinia()
pinia.use(({ store }) => {
// 监控 action 性能
store.$onAction(({ name, after, onError }) => {
const start = Date.now()
after(() => {
const duration = Date.now() - start
console.log(`Action ${name} 耗时 ${duration}ms`)
})
onError((error) => {
console.error(`Action ${name} 失败:`, error)
})
})
// 监控状态变化
store.$subscribe((mutation, state) => {
console.log('状态变化:', mutation.type, mutation.payload)
})
})
return pinia
}
TypeScript
自定义属性类型
ts
import 'pinia'
import type { Router } from 'vue-router'
import type { AxiosInstance } from 'axios'
declare module 'pinia' {
export interface PiniaCustomProperties {
$router: Router
$api: AxiosInstance
}
}
// 现在 TypeScript 知道自定义属性
const pinia = createPinia()
pinia.use(({ store }) => {
store.$router = router // ✅ 有类型
store.$api = api // ✅ 有类型
})
通用 Pinia 工厂
ts
interface PiniaConfig {
plugins?: PiniaPlugin[]
devtools?: boolean
}
function createConfiguredPinia(config: PiniaConfig = {}): Pinia {
const pinia = createPinia()
// 添加插件
config.plugins?.forEach(plugin => {
pinia.use(plugin)
})
// 配置开发工具
if (config.devtools && process.env.NODE_ENV === 'development') {
pinia.use(devtoolsPlugin)
}
return pinia
}
错误处理
全局错误处理器
js
import { createPinia } from 'pinia'
function createRobustPinia() {
const pinia = createPinia()
pinia.use(({ store }) => {
// 全局错误处理
store.$onAction(({ name, onError }) => {
onError((error) => {
console.error(`Store action ${name} 失败:`, error)
// 报告给错误跟踪服务
errorTracker.captureException(error, {
tags: {
store: store.$id,
action: name
}
})
})
})
})
return pinia
}
回退状态
js
import { createPinia } from 'pinia'
function createFallbackPinia() {
const pinia = createPinia()
pinia.use(({ store, options }) => {
// 添加回退状态
store.$fallback = () => {
if (typeof options.state === 'function') {
store.$patch(options.state())
}
}
// 关键错误时自动回退
store.$onAction(({ name, onError }) => {
onError((error) => {
if (error.critical) {
store.$fallback()
}
})
})
})
return pinia
}
最佳实践
1. 每个应用一个实例
js
// ✅ 好 - 每个应用一个实例
const pinia = createPinia()
app.use(pinia)
// ❌ 避免 - 无理由的多个实例
const pinia1 = createPinia()
const pinia2 = createPinia()
2. 使用前配置
js
// ✅ 好 - 使用前配置
const pinia = createPinia()
pinia.use(persistencePlugin)
pinia.use(routerPlugin)
app.use(pinia)
// ❌ 避免 - 安装后添加插件
app.use(pinia)
pinia.use(latePlugin) // 可能不会影响现有 store
3. 环境特定配置
js
// ✅ 好 - 环境感知设置
const pinia = createPinia()
if (process.env.NODE_ENV === 'development') {
pinia.use(loggerPlugin)
pinia.use(devtoolsPlugin)
}
if (process.env.NODE_ENV === 'production') {
pinia.use(analyticsPlugin)
pinia.use(errorReportingPlugin)
}
4. 插件顺序很重要
js
// ✅ 好 - 逻辑插件顺序
const pinia = createPinia()
pinia.use(routerPlugin) // 基础功能
pinia.use(persistencePlugin) // 依赖状态
pinia.use(loggerPlugin) // 应该最后添加以完整记录
常见模式
工厂模式
js
function createAppPinia() {
const pinia = createPinia()
// 标准插件
pinia.use(routerPlugin)
pinia.use(persistencePlugin)
// 环境特定
if (import.meta.env.DEV) {
pinia.use(loggerPlugin)
}
return pinia
}
// 用法
const pinia = createAppPinia()
app.use(pinia)
懒加载插件
js
async function createAsyncPinia() {
const pinia = createPinia()
// 动态加载插件
if (shouldUsePersistence) {
const { createPersistedState } = await import('pinia-plugin-persistedstate')
pinia.use(createPersistedState())
}
return pinia
}
生命周期
安装
createPinia()
创建新实例app.use(pinia)
安装插件- Pinia 设置全局属性并提供实例
Store 创建
defineStore()
注册 store 定义- 首次调用
useStore()
创建 store 实例 - 插件应用到新 store
- Store 添加到 Pinia 实例
清理
- 应用卸载时,Pinia 清理所有 store
- Effect scope 被销毁
- 订阅被移除