Appearance
Pinia 源代码导览
项目结构
pinia-course/
├── 04-core-feature/ # 核心功能实现
│ ├── src/
│ │ ├── pinia.js # Pinia 实例
│ │ ├── store.js # Store
│ │ └── reactive.js # 响应式
│ ├── test/
│ │ ├── pinia.test.js
│ │ ├── store.test.js
│ │ └── reactive.test.js
│ ├── package.json
│ └── README.md
├── 05-lesson-plan.md # 课程计划
├── 01-intro.md # 背景研究
├── 02-arch.md # 架构分析
└── 03-code-walkthrough.md # 源代码导览核心文件解析
1. pinia.js - Pinia 实例
文件路径: src/pinia.js
核心功能: 管理 Store,插件系统,DevTools 集成。
关键代码:
javascript
import { reactive, effectScope } from 'vue'
// Pinia 符号
export const piniaSymbol = Symbol()
// Pinia 实例
export class Pinia {
constructor() {
this._s = new Map() // Store 映射
this.state = reactive({}) // 全局状态
this._p = [] // 插件
this._a = null // Vue 应用
this._e = effectScope(true) // 作用域
}
// 安装 Pinia
install(app) {
this._a = app
app.provide(piniaSymbol, this)
app.config.globalProperties.$pinia = this
// 初始化插件
this._p.forEach(plugin => plugin({ pinia: this, app }))
}
// 使用插件
use(plugin) {
this._p.push(plugin)
if (this._a) {
plugin({ pinia: this, app: this._a })
}
return this
}
// 获取 Store
get store() {
return this._s
}
// 获取状态
get state() {
return this.state
}
}
// 创建 Pinia 实例
export function createPinia() {
return new Pinia()
}设计要点: 使用 Map 存储 Store,支持插件系统,与 Vue 集成。
2. store.js - Store
文件路径: src/store.js
核心功能: 定义 Store,管理状态,提供方法。
关键代码:
javascript
import { reactive, computed, watch } from 'vue'
// 定义 Store
export function defineStore(id, options) {
const { state, getters, actions } = options
return function useStore(pinia) {
pinia = pinia || activePinia
if (!pinia._s.has(id)) {
createStore(id, state, getters, actions, pinia)
}
return pinia._s.get(id)
}
}
// 创建 Store
function createStore(id, state, getters, actions, pinia) {
const initialState = state ? state() : {}
const store = reactive({
$id: id,
$state: initialState,
$patch: (partialStateOrMutator) => {
if (typeof partialStateOrMutator === 'function') {
partialStateOrMutator(store.$state)
} else {
Object.assign(store.$state, partialStateOrMutator)
}
},
$reset: () => {
if (state) {
Object.assign(store.$state, state())
}
},
$dispose: () => {
pinia._s.delete(id)
}
})
// 添加 getters
if (getters) {
Object.keys(getters).forEach(key => {
Object.defineProperty(store, key, {
get: () => getters[key].call(store, store),
enumerable: true
})
})
}
// 添加 actions
if (actions) {
Object.keys(actions).forEach(key => {
store[key] = (...args) => actions[key].apply(store, args)
})
}
// 添加到 Pinia
pinia._s.set(id, store)
pinia.state[id] = store.$state
return store
}
// 活跃的 Pinia 实例
let activePinia = null
// 设置活跃的 Pinia 实例
export function setActivePinia(pinia) {
activePinia = pinia
}设计要点: 使用 reactive 创建响应式状态,支持计算属性,支持方法。
3. reactive.js - 响应式
文件路径: src/reactive.js
核心功能: 响应式状态,计算属性,监听。
关键代码:
javascript
import { reactive, computed, watch } from 'vue'
// 创建响应式状态
export function createState(initialState) {
return reactive(initialState)
}
// 创建计算属性
export function createGetter(getter) {
return computed(getter)
}
// 创建监听器
export function createWatcher(source, callback, options = {}) {
return watch(source, callback, options)
}
// 创建 Store 响应式
export function createStoreReactive(store, pinia) {
// 监听状态变化
watch(
() => store.$state,
(newState) => {
pinia.state[store.$id] = newState
},
{ deep: true }
)
return store
}设计要点: 使用 Vue 3 的响应式 API,支持计算属性,支持监听。
关键设计决策
1. 使用 Map 存储 Store
原因: 快速查找,自动去重,内存效率高。
实现:
javascript
this._s = new Map()
// 添加 Store
this._s.set(id, store)
// 获取 Store
const store = this._s.get(id)2. 使用 reactive
原因: 响应式状态,自动追踪,高效更新。
实现:
javascript
const store = reactive({
$id: id,
$state: initialState
})3. 支持插件系统
原因: 灵活扩展,社区贡献,功能增强。
实现:
javascript
pinia.use(plugin)
// 插件结构
function plugin({ pinia, app, store }) {
// 插件逻辑
}测试策略
单元测试
javascript
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { createPinia, defineStore } from '../src/pinia.js'
describe('Pinia 测试', () => {
it('应该创建 Pinia 实例', () => {
const pinia = createPinia()
assert.ok(pinia)
})
it('应该创建 Store', () => {
const pinia = createPinia()
const useStore = defineStore('counter', {
state: () => ({
count: 0
})
})
const store = useStore(pinia)
assert.ok(store)
assert.strictEqual(store.count, 0)
})
})性能优化
1. 计算属性缓存
javascript
const doubleCount = computed(() => store.count * 2) // 自动缓存2. 按需订阅
javascript
watch(
() => store.count, // 只订阅 count
(newVal) => {
console.log(newVal)
}
)3. 懒加载 Store
javascript
const store = useStore() // 懒加载总结
Pinia 的源代码体现了四个核心设计原则:简洁提供简洁的 API,降低学习成本;响应式使用 Vue 3 的响应式系统,实现高效的状态更新;插件化支持插件扩展,满足定制化需求;类型安全提供完整的 TypeScript 支持,实现完美的类型推断。理解源代码有助于更好地使用和优化 Pinia。
参考资源
Pinia 源码,Pinia 官方文档,Vue.js 官方文档。

扫描二维码关注"架构师AI杜"公众号,获取更多技术内容和最新动态
