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。
参考资源

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