更新记录
0.0.6(2026-04-30) 下载此版本
新增功能
- ✅ Store ID 重复检查 - 在
defineStore中添加检查,当发现相同 id 被不同 store 使用时抛出明确的错误提示
0.0.5(2026-04-23) 下载此版本
新增功能
- ✅ Store 间通信 - 新增
useStore<T>(id: string)方法,支持在 store 内部获取其他 store 实例
性能优化
- ✅ 持久化性能优化 - 实现防抖保存,避免频繁存储,提高性能
优化改进
- ✅ 条件编译引入 vue - 在非 UNI-APP-X 环境下引入 vue 相关方法
- ✅ 简化使用 - 用户只需定义
state = reactive({...}),无需额外操作
错误处理优化
- ✅ 完善的错误提示 - 区分未定义 state 和非 reactive 对象两种错误情况,提供更清晰的错误信息
0.0.4(2026-04-22) 下载此版本
新增功能
- ✅ Store 间通信 - 新增
useStore<T>(id: string)方法,支持在 store 内部获取其他 store 实例
性能优化
- ✅ 持久化性能优化 - 实现防抖保存,避免频繁存储,提高性能
平台兼容性
uni-app(5.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| - | √ | √ | √ | √ | - | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
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 - ✅ 把 state 定义在最前面,在访问 state 之前先定义好,要严格按顺序来
示例:
import { defineStore, PiniaStore } from '@/uni_modules/lime-pinia'
import { reactive, computed } 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()
}
// 【方式一:Getters】类的 Getter 方式
get info(): string {
return `姓名: ${this.state.name}, 年龄: ${this.state.age}岁`
}
// 【方式二:Computed】Vue 的 computed 方式
displayName = computed(() => {
return `用户:${this.state.name}`
})
// 定义业务方法(建议用 $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()
$dispose() - 清理资源
清理 store 的所有资源,包括监听器、订阅和状态:
import { useUserStore } from '@/stores/user'
const user = useUserStore()
// 清理 store
user.$dispose()
// 清理后,store 不能再使用
// user.state.name // 会报错
Store 间通信
使用 useStore<T>(id: string) 方法在 store 内部获取其他 store 实例:
// user.ts
import { PiniaStore, defineStore } from 'lime-pinia'
import { reactive } from 'vue'
import type { CounterStore } from './counter'
class UserStore extends PiniaStore<{
name: string
age: number
}> {
state = reactive({
name: '张三',
age: 25
})
constructor() {
super()
}
// 在 user store 中使用 counter store
incrementCounter() {
const counterStore = this._p!.useStore<CounterStore>('counter')
counterStore.increment()
}
}
export const useUserStore = defineStore('user', new UserStore())
订阅(监听)
$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 的持久化
7. 关键说明
API 速查表
| 属性/方法 | 用途 |
|---|---|
$id |
Store 的唯一 ID |
$state |
获取当前状态 |
$patch() |
批量修改状态 |
$reset() |
重置到初始状态 |
$subscribe() |
订阅状态变化 |
$onAction() |
订阅动作执行 |
$action() |
包装方法以支持订阅 |
$dispose() |
清理 store 资源 |
重要注意事项
- 必须用
reactive()定义 state - 必须把 state 定义在最前面,在访问 state 之前先定义好,要严格按顺序来
- 建议用
$action包装业务方法,这样$onAction才能工作 - 持久化插件会在
$patch()、$reset()或$action()调用时自动保存 - 与原始 Pinia 的 Option / Setup Store 不一样,这是 class-based 的实现方式
8. 从原始 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()
}
// 将 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()
}
// 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 订阅 |
支持与赞赏
如果你觉得本插件解决了你的问题,可以考虑支持作者:
| 支付宝赞助 | 微信赞助 |
|---|---|
![]() |
![]() |

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


下载 72215
赞赏 576
下载 12174462
赞赏 1918
赞赏
京公网安备:11010802035340号