Appearance
Pinia 课程计划
课程概述
本课程将带你从零开始实现一个状态管理系统,理解 Pinia 的核心原理。
课程目标
- 理解状态管理的原理
- 掌握 Store 的定义和使用
- 学习响应式状态和动作
- 能够构建自己的状态管理库
课程结构
8 节课,每节 20-40 分钟,总时长约 90-120 分钟。
第 1 课:Pinia 简介
目标
- 了解 Pinia 的背景
- 理解状态管理的概念
- 掌握 Pinia 的核心功能
内容
Pinia 背景
- 什么是 Pinia
- 为什么需要状态管理
- Pinia vs Vuex
核心概念
- Store
- State
- Getters
- Actions
Pinia 的优势
- TypeScript 支持
- 模块化设计
- 更简洁的 API
实践步骤
bash
# 1. 创建项目
mkdir pinia-course
cd pinia-course
# 2. 初始化项目
npm init -y
# 3. 安装 Vue
npm install vue --save预期输出
✓ 项目初始化完成
✓ Vue 安装完成总结
- ✅ 理解了状态管理的概念
- ✅ 掌握了核心功能
- ✅ 了解了 Pinia 的优势
第 2 课:Store 定义
目标
- 理解 Store 的原理
- 实现 Store 定义
- 学习 Store 配置
内容
Store 定义
- 什么是 Store
- Store 结构
- Store 配置
实现 Store
- State 定义
- Getter 定义
- Action 定义
测试 Store
- 单元测试
- 集成测试
实践步骤
bash
# 1. 创建 Store
cat > src/store.js << 'EOF'
export function createStore(options) {
const store = {
id: options.id,
state: options.state || {},
getters: options.getters || {},
actions: options.actions || {}
}
return store
}
EOF
# 2. 创建测试
cat > test/store.test.js << 'EOF'
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { createStore } from '../src/store.js'
describe('Store 测试', () => {
it('应该创建 Store', () => {
const store = createStore({
id: 'main',
state: { count: 0 }
})
assert.ok(store)
assert.strictEqual(store.id, 'main')
})
})
EOF
# 3. 运行测试
npm test预期输出
✓ 应该创建 Store总结
- ✅ 实现了 Store 定义
- ✅ 理解了 Store 结构
- ✅ 掌握了 Store 配置
第 3 课:响应式状态
目标
- 理解响应式状态的原理
- 实现响应式状态
- 学习状态订阅
内容
响应式状态
- 什么是响应式
- Proxy 原理
- 依赖收集
实现响应式状态
- Proxy 拦截
- 状态更新
- 依赖通知
测试响应式状态
- 单元测试
- 集成测试
实践步骤
bash
# 1. 创建响应式状态
cat > src/reactive.js << 'EOF'
export function reactive(obj) {
const listeners = new Map()
return new Proxy(obj, {
get(target, key) {
// 依赖收集
return target[key]
},
set(target, key, value) {
target[key] = value
// 通知监听器
notify(key, value)
return true
}
})
function notify(key, value) {
const keyListeners = listeners.get(key) || []
keyListeners.forEach(listener => listener(value))
}
}
EOF
# 2. 创建测试
cat > test/reactive.test.js << 'EOF'
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { reactive } from '../src/reactive.js'
describe('响应式状态测试', () => {
it('应该创建响应式对象', () => {
const state = reactive({ count: 0 })
assert.ok(state)
})
it('应该更新状态', () => {
const state = reactive({ count: 0 })
state.count = 1
assert.strictEqual(state.count, 1)
})
})
EOF
# 3. 运行测试
npm test预期输出
✓ 应该创建响应式对象
✓ 应该更新状态总结
- ✅ 实现了响应式状态
- ✅ 理解了 Proxy 原理
- ✅ 掌握了状态订阅
第 4 课:Getters
目标
- 理解 Getters 的原理
- 实现 Getters
- 学习计算属性
内容
Getters
- 什么是 Getters
- Getter 原理
- 缓存机制
实现 Getters
- Getter 定义
- 缓存实现
- 依赖追踪
测试 Getters
- 单元测试
- 集成测试
实践步骤
bash
# 1. 创建 Getters
cat > src/getters.js << 'EOF'
export function createGetters(state, getters) {
const computedGetters = {}
for (const key in getters) {
let cache = null
let dirty = true
computedGetters[key] = {
get() {
if (dirty) {
cache = getters[key].call(state, state)
dirty = false
}
return cache
},
set() {
dirty = true
}
}
}
return computedGetters
}
EOF
# 2. 创建测试
cat > test/getters.test.js << 'EOF'
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { createGetters } from '../src/getters.js'
describe('Getters 测试', () => {
it('应该创建 Getters', () => {
const state = { count: 0 }
const getters = {
double: (state) => state.count * 2
}
const computedGetters = createGetters(state, getters)
assert.ok(computedGetters)
})
it('应该计算 Getter', () => {
const state = { count: 5 }
const getters = {
double: (state) => state.count * 2
}
const computedGetters = createGetters(state, getters)
assert.strictEqual(computedGetters.double.get(), 10)
})
})
EOF
# 3. 运行测试
npm test预期输出
✓ 应该创建 Getters
✓ 应该计算 Getter总结
- ✅ 实现了 Getters
- ✅ 理解了缓存机制
- ✅ 掌握了计算属性
第 5 课:Actions
目标
- 理解 Actions 的原理
- 实现 Actions
- 学习异步处理
内容
Actions
- 什么是 Actions
- Action 原理
- 异步处理
实现 Actions
- Action 定义
- 上下文绑定
- 错误处理
测试 Actions
- 单元测试
- 集成测试
实践步骤
bash
# 1. 创建 Actions
cat > src/actions.js << 'EOF'
export function createActions(store, actions) {
const boundActions = {}
for (const key in actions) {
boundActions[key] = async (...args) => {
try {
return await actions[key].call(store, ...args)
} catch (error) {
console.error(`Action ${key} failed:`, error)
throw error
}
}
}
return boundActions
}
EOF
# 2. 创建测试
cat > test/actions.test.js << 'EOF'
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { createActions } from '../src/actions.js'
describe('Actions 测试', () => {
it('应该创建 Actions', () => {
const store = { state: { count: 0 } }
const actions = {
increment: function() {
this.state.count++
}
}
const boundActions = createActions(store, actions)
assert.ok(boundActions)
})
it('应该执行 Action', async () => {
const store = { state: { count: 0 } }
const actions = {
increment: function() {
this.state.count++
}
}
const boundActions = createActions(store, actions)
await boundActions.increment()
assert.strictEqual(store.state.count, 1)
})
})
EOF
# 3. 运行测试
npm test预期输出
✓ 应该创建 Actions
✓ 应该执行 Action总结
- ✅ 实现了 Actions
- ✅ 理解了上下文绑定
- ✅ 掌握了异步处理
第 6 课:模块化
目标
- 理解模块化的原理
- 实现模块化 Store
- 学习 Store 组合
内容
模块化
- 什么是模块化
- 模块隔离
- 模块通信
实现模块化
- Store 注册
- 模块访问
- 模块通信
测试模块化
- 单元测试
- 集成测试
实践步骤
bash
# 1. 创建模块化
cat > src/modules.js << 'EOF'
export function createPinia() {
const stores = new Map()
return {
defineStore(id, setup) {
const store = setup()
stores.set(id, store)
return store
},
getStore(id) {
return stores.get(id)
},
removeStore(id) {
stores.delete(id)
}
}
}
EOF
# 2. 创建测试
cat > test/modules.test.js << 'EOF'
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { createPinia } from '../src/modules.js'
describe('模块化测试', () => {
it('应该创建 Pinia', () => {
const pinia = createPinia()
assert.ok(pinia)
})
it('应该定义 Store', () => {
const pinia = createPinia()
const store = pinia.defineStore('main', () => ({
state: { count: 0 }
}))
assert.ok(store)
})
})
EOF
# 3. 运行测试
npm test预期输出
✓ 应该创建 Pinia
✓ 应该定义 Store总结
- ✅ 实现了模块化
- ✅ 理解了模块隔离
- ✅ 掌握了模块通信
第 7 课:持久化
目标
- 理解持久化的原理
- 实现状态持久化
- 学习存储策略
内容
持久化
- 什么是持久化
- 持久化策略
- 存储方案
实现持久化
- LocalStorage
- SessionStorage
- 自定义存储
测试持久化
- 单元测试
- 集成测试
实践步骤
bash
# 1. 创建持久化
cat > src/persist.js << 'EOF'
export function createPersistPlugin(options = {}) {
const storage = options.storage || localStorage
const key = options.key || 'pinia'
return {
install(store) {
// 从存储恢复状态
const saved = storage.getItem(key)
if (saved) {
Object.assign(store.state, JSON.parse(saved))
}
// 监听状态变化
store.$subscribe((mutation, state) => {
storage.setItem(key, JSON.stringify(state))
})
}
}
}
EOF
# 2. 创建测试
cat > test/persist.test.js << 'EOF'
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { createPersistPlugin } from '../src/persist.js'
describe('持久化测试', () => {
it('应该创建持久化插件', () => {
const plugin = createPersistPlugin()
assert.ok(plugin)
})
})
EOF
# 3. 运行测试
npm test预期输出
✓ 应该创建持久化插件总结
- ✅ 实现了持久化
- ✅ 理解了存储策略
- ✅ 掌握了状态恢复
第 8 课:总结与扩展
目标
- 总结所有课程
- 回顾关键概念
- 提供扩展建议
内容
课程总结
- 回顾所有功能
- 总结关键概念
- 展示完整代码
扩展建议
- 添加更多功能
- 优化性能
- 支持更多特性
下一步
- 学习 Pinia 源码
- 参与开源项目
- 构建自己的状态管理库
总结
通过本课程,你学会了:
- ✅ Pinia 简介
- ✅ Store 定义
- ✅ 响应式状态
- ✅ Getters
- ✅ Actions
- ✅ 模块化
- ✅ 持久化
下一步
- 学习 Pinia 源码
- 添加更多功能
- 参与开源项目
参考资源

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