更新记录
0.0.1(2026-04-22) 下载此版本
新增功能
-
✅ class-based PiniaStore 基类实现
- 使用 reactive 定义 state
- bindState() 绑定响应式状态
- 完整的 $id 和 $state 支持
-
✅ 核心 API 实现
$patch()- 批量修改状态(对象/函数方式)$reset()- 重置到初始状态$subscribe()- 订阅状态变化$onAction()- 订阅动作执行$action()- 包装方法以支持订阅
-
✅ 持久化插件
- uni.setStorageSync 自动保存
- 支持 keyPrefix 配置
- 支持 includeStores / excludeStores 过滤
- 支持自定义序列化
- clearPersistedState() 手动清除
-
✅ 插件机制
- createPinia() 创建根实例
- use() 注册插件
- 插件上下文支持 storeId、pinia、store 等
-
✅ 模块化架构
- types.uts - 类型定义
- createPinia.uts - Pinia 根实例创建
- store.uts - PiniaStore 基类
- persist.uts - 持久化插件
- index.uts - 统一导出
文档
平台兼容性
uni-app x(5.03)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ |
lime-pinia
Pinia 状态管理库,专为 uni-app-x 设计,使用 UTS 实现的 class-based 版本
快速开始
安装
在 uni-app 插件市场中搜索并导入 lime-pinia
基础使用步骤
- 在 main.uts 中初始化 Pinia
- 定义你自己的 Store
- 在页面或组件中使用
1. 初始化 Pinia
在你的项目入口 main.uts 中:
import { createSSRApp } from 'vue'
import App from './App.uvue'
import { createPinia, createPersistPlugin } from '@/uni_modules/lime-pinia'
export function createApp() {
const app = createSSRApp(App)
const pinia = createPinia()
// (可选)开启持久化
pinia.use(createPersistPlugin())
app.use(pinia)
return {
app
}
}
2. 定义你的 Store
继承 PiniaStore 类即可。
**必须做的两件事:
- ✅ 使用
reactive()定义 state - ✅ 在构造函数中调用
this.bindState(state)
示例:
import { defineStore, PiniaStore } from '@/uni_modules/lime-pinia'
import { reactive } from 'vue'
// 第一步:定义你的 State 类型
export type UserState = {
name : string
age : number
theme : 'light' | 'dark'
}
// 第二步:继承 PiniaStore
export class UserStore extends PiniaStore<UserState> {
// 【必须】用 reactive 创建响应式状态
state = reactive<UserState>({
name: '张三',
age: 25,
theme: 'light'
})
constructor() {
super()
// 【必须】绑定 state
this.bindState(this.state)
}
// 定义业务方法(建议用 $action 包装)
setName(name: string) {
this.$action('setName', () => {
this.state.name = name
}, [name])
}
setAge(age: number) {
this.$action('setAge', () => {
this.state.age = age
}, [age])
}
toggleTheme() {
this.$action('toggleTheme', () => {
this.state.theme = this.state.theme == 'light' ? 'dark' : 'light'
})
}
}
// 第三步:创建 use 函数
export const useUserStore = defineStore<UserState, UserStore>('user', new UserStore())
3. 在页面中使用
<view class="container">
<text>姓名: {{ user.state.name }}</text>
<text>年龄: {{ user.state.age }}</text>
<text>主题: {{ user.state.theme }}</text>
<input v-model="nameInput" placeholder="输入姓名" />
<button @click="updateName">更新姓名</button>
<input v-model="ageInput" placeholder="输入年龄" />
<button @click="updateAge">更新年龄</button>
<button @click="toggleTheme">切换主题</button>
<button @click="resetStore">重置</button>
</view>
import { ref } from 'vue'
import { useUserStore } from '@/stores/user'
const user = useUserStore()
const nameInput = ref('')
const ageInput = ref('')
function updateName() {
if (nameInput.value != '') {
user.setName(nameInput.value)
}
}
function updateAge() {
const age = parseInt(ageInput.value)
if (isNaN(age) != true) {
user.setAge(age)
}
}
function toggleTheme() {
user.toggleTheme()
}
function resetStore() {
user.$reset()
nameInput.value = ''
ageInput.value = ''
}
4. 核心 API 速查
访问数据和状态操作
$patch() - 批量修改
// 对象方式
user.$patch({
name: '李四',
age: 30
})
// 函数方式
user.$patch((state) => {
state.name = '王五'
state.age = 35
})
$reset() - 重置到初始值
user.$reset()
订阅(监听)
$subscribe() - 监听状态变化
import { onMounted, onUnmounted } from 'vue'
import { useUserStore } from '@/stores/user'
const user = useUserStore()
let unsubscribe = null
onMounted(() => {
unsubscribe = user.$subscribe((mutation, state) => {
console.log('变化类型:', mutation.type)
console.log('最新状态:', state)
})
})
onUnmounted(() => {
unsubscribe?.()
})
$onAction() - 监听动作执行
import { onMounted, onUnmounted } from 'vue'
import { useUserStore } from '@/stores/user'
const user = useUserStore()
let unsubscribe = null
onMounted(() => {
unsubscribe = user.$onAction((ctx, after, onError) => {
console.log('执行的动作:', ctx.name)
after((result) => {
console.log('执行完成:', result)
})
onError((error) => {
console.error('执行出错:', error)
})
})
})
onUnmounted(() => {
unsubscribe?.()
})
4. 持久化插件使用
基本使用
import { createPersistPlugin } from '@/uni_modules/lime-pinia'
const pinia = createPinia()
pinia.use(createPersistPlugin())
app.use(pinia)
自定义配置
pinia.use(createPersistPlugin({
keyPrefix: 'my-pinia-', // 存储前缀
includeStores: ['user', 'counter'], // 只持久化这些 store
excludeStores: [], // 排除这些
serializer: null // 自定义序列化
}))
手动清除持久化
import { clearPersistedState } from '@/uni_modules/lime-pinia'
clearPersistedState('user') // 清除名为 user 的持久化
6. 关键说明
API 速查表
| 属性/方法 | 用途 |
|---|---|
$id |
Store 的唯一 ID |
$state |
获取当前状态 |
$patch() |
批量修改状态 |
$reset() |
重置到初始状态 |
$subscribe() |
订阅状态变化 |
$onAction() |
订阅动作执行 |
$action() |
包装方法以支持订阅 |
bindState() |
绑定响应式 state |
重要注意事项
- 必须用
reactive()定义 state - 继承
PiniaStore的类,必须在构造函数中调用this.bindState(state) - 建议用
$action包装业务方法,这样$onAction才能工作 - 持久化插件会在
$patch()、$reset()或$action()调用时自动保存 - 与原始 Pinia 的 Option / Setup Store 不一样,这是 class-based 的实现方式
7. 从原始 Pinia 转换
如果你正在使用原始 Pinia,下面是转换到 lime-pinia 的快速对比:
原始 Pinia (Options Store)
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: '张三',
age: 25,
theme: 'light'
}),
actions: {
setName(name: string) {
this.name = name
},
setAge(age: number) {
this.age = age
},
toggleTheme() {
this.theme = this.theme == 'light' ? 'dark' : 'light'
}
}
})
原始 Pinia (Setup Store) - ⚠️ 不支持
原始 Pinia 也支持 setup 风格,但 lime-pinia 不支持,因为我们使用的是 class-based 风格:
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useUserStore = defineStore('user', () => {
const name = ref('张三')
const age = ref(25)
const theme = ref('light')
const setName = (nameValue: string) => {
name.value = nameValue
}
const setAge = (ageValue: number) => {
age.value = ageValue
}
const toggleTheme = () => {
theme.value = theme.value == 'light' ? 'dark' : 'light'
}
return {
name,
age,
theme,
setName,
setAge,
toggleTheme
}
})
⚠️ lime-pinia 不支持 setup store 风格,请使用 class-based 风格
从 Setup Store 转换
如果你正在使用 setup store,下面是如何转换到 lime-pinia:
// 原始 setup store
export const useUserStore = defineStore('user', () => {
const name = ref('张三')
const age = ref(25)
const theme = ref('light')
const setName = (nameValue: string) => {
name.value = nameValue
}
// ...
})
// 转换为 lime-pinia
class UserStore extends PiniaStore<UserState> {
state = reactive<UserState>({
name: '张三',
age: 25,
theme: 'light'
})
constructor() {
super()
this.bindState(this.state)
}
// 将 ref 改为 state 访问,.value 去掉
setName(name: string) {
this.$action('setName', () => {
this.state.name = name // 原来是 name.value = name
}, [name])
}
// ...
}
转换为 lime-pinia
import { defineStore, PiniaStore } from '@/uni_modules/lime-pinia'
import { reactive } from 'vue'
// 1. 定义 State 类型
type UserState = {
name: string
age: number
theme: 'light' | 'dark'
}
// 2. 继承 PiniaStore
class UserStore extends PiniaStore<UserState> {
// 3. 使用 reactive 定义 state
state = reactive<UserState>({
name: '张三',
age: 25,
theme: 'light'
})
constructor() {
super()
// 4. 在构造函数中绑定 state
this.bindState(this.state)
}
// 5. 定义业务方法(建议用 $action 包装)
setName(name: string) {
this.$action('setName', () => {
this.state.name = name
}, [name])
}
setAge(age: number) {
this.$action('setAge', () => {
this.state.age = age
}, [age])
}
toggleTheme() {
this.$action('toggleTheme', () => {
this.state.theme = this.state.theme == 'light' ? 'dark' : 'light'
})
}
}
// 6. 创建 use 函数
export const useUserStore = defineStore<UserState, UserStore>('user', new UserStore())
转换要点总结
| 原始 Pinia | lime-pinia | 说明 |
|---|---|---|
state: () => ({ ... }) |
state = reactive({ ... }) |
使用 reactive |
const name = ref(...) |
state.name |
将 ref 合并到 state 对象 |
name.value |
this.state.name |
去掉 .value |
this.name |
this.state.name |
通过 .state 访问 |
| actions 中的方法 | 类方法,建议用 $action 包装 |
支持 $onAction 订阅 |
| - | 构造函数中调用 this.bindState(this.state) |
必须 |
支持与赞赏
如果你觉得本插件解决了你的问题,可以考虑支持作者:
| 支付宝赞助 | 微信赞助 |
|---|---|
![]() |
![]() |

收藏人数:
下载插件并导入HBuilderX
赞赏(0)


下载 70936
赞赏 564
下载 11628895
赞赏 1907
赞赏
京公网安备:11010802035340号