@haixing_hu/pinia-decorator
v3.3.0
Published
Provides class fields decorators for Pinia and vue3-class-component.
Downloads
306
Maintainers
Readme
pinia-decorator
pinia-decorator 是一个 JavaScript 库,它使用了 JavaScript 装饰器的第三阶段提案, 简化了将 Pinia 存储与 Vue 类风格组件 集成的过程。换句话说,它提供了类似于 vuex-class 和 pinia-class 库的功能。
该库受 vuex-class 和 pinia-class 的启发,但存在一些关键区别:
- 它是用纯 JavaScript 实现的,不需要 TypeScript 支持。
- 它支持 Vue 3。
- 它支持使用 vue3-class-component 实现的 JavaScript 类风格 Vue 组件, 而 pinia-class 主要针对使用 vue-facing-decorator 实现的 TypeScript 类风格 Vue 组件。
- 它支持使用
@DefineStore
装饰器将一个类定义为 Pinia 存储。
目录
安装
你可以通过 npm 或 yarn 安装 pinia-decorator:
npm install @haixing_hu/pinia-decorator
或
yarn add @haixing_hu/pinia-decorator
使用
pinia-decorator 为 [Vue 3 类风格组件] 提供了以下装饰器:
@State
:用于将只读状态从 Pinia 存储注入到组件中。@WritableState
:用于将可写状态从 Pinia 存储注入到组件中。@Getter
:用于将 getter 从 Pinia 存储注入到组件中。@Action
:用于将 action 从 Pinia 存储注入到组件中。@Store
:用于将整个 Pinia 存储注入到组件中。@DefineStore
:用于将一个类定义为 Pinia 存储。
@State
@State
装饰器用于将只读状态从 Pinia 存储注入到 Vue 类风格组件 中。
它允许你在组件内部访问和使用 Pinia 存储的状态。
@State
装饰器的语法如下:
@State(store: Object, stateName?: string)
store
(必需):使用Pinia
的defineStore()
函数定义的待注入的 Pinia 存储对象。stateName
(可选):待注入的状态在 Pinia 存储中的名称。如果未提供, 装饰器将使用被装饰的字段名作为待注入的状态的名称。
@WritableState
@WritableState
装饰器与 @State
类似,但它允许你将可写状态从 Pinia 存储注入到
Vue 类风格组件 中。这意味着你可以在组件内部既读取又修改 Pinia 存储的状态值。
@WritableState
装饰器的语法如下:
@WritableState(store: Object, stateName?: string)
store
(必需):使用Pinia
的defineStore()
函数定义的待注入的 Pinia 存储对象。stateName
(可选):待注入的状态在 Pinia 存储中的名称。如果未提供, 装饰器将使用被装饰的字段名作为待注入的状态的名称。
@Getter
@Getter
装饰器用于将 getter 从 Pinia 存储注入到 Vue 类风格组件 中。
它允许你在组件内部调用 Pinia 存储的 getter 函数。
@Getter
装饰器的语法如下:
@Getter(store: Object, getterName?: string)
store
(必需):使用Pinia
的defineStore()
函数定义的待注入的 Pinia 存储对象。getterName
(可选):待注入的 getter 在 Pinia 存储中的名称。如果未提供, 装饰器将使用被装饰的字段名作为待注入的 getter 的名称。
@Action
@Action
装饰器用于将 action 从 Pinia 存储注入到 Vue 类风格组件 中。
它允许你在组件内部调用存储的 action 函数。
@Action
装饰器的语法如下:
@Action(store: Object, actionName?: string)
store
(必需):使用Pinia
的defineStore()
函数定义的待注入的 Pinia 存储对象。actionName
(可选):待注入的 action 在 Pinia 存储中的名称。如果未提供, 装饰器将使用被装饰的字段名作为待注入的 action 的名称。
@Store
@Store
装饰器用于将整个 Pinia 存储注入到 Vue 类风格组件中。它允许你访问存储的所有状态、
getter 和 action。
@Store
装饰器的语法如下:
@Store(store: Object)
store
(必需):使用Pinia
的defineStore()
函数定义的待注入的 Pinia 存储对象的创建函数。
toStore()
toStore()
函数用于将一个类定义为 Pinia 存储。它允许你定义一个类,该类的实例将作为 Pinia 存储的实例。
toStore()
函数的语法如下:
toStore(storeId: string, Class: function)
storeId
(必需):Pinia 存储的ID。Class
(必需):待定义为 Pinia 存储的类。
@RawField
@RawField
装饰器用于将一个类的字段标记为原始字段,这样该类被转换为 Pinia store 后,该
字段表示的状态不会被转换为响应式状态。
示例
以下是如何在 Vue 组件中使用这些装饰器的简单示例:
import { Component, toVue } from '@haixing_hu/vue3-class-component';
import { State, WritableState, Getter, Action, Store } from '@haixing_hu/pinia-decorator';
import { useMyStore } from './my-pinia-store-module';
@Component
export class MyComponent extends Vue {
@State(useMyStore)
myValue;
@State(useMyStore, 'message')
myMessage;
@Getter(useMyStore)
myGetter
@Getter(useMyStore, 'count')
myCountGetter
@Action(useMyStore)
fetchData;
@Action(useMyStore, 'sayMessage')
mySayMessage;
@Store(useMyStore)
store;
someOtherMessage = 'Hello World!';
callSayMessage() {
console.log('MyComponent.callSayMessage');
this.mySayMessage(this.myMessage);
}
}
export default toVue(MyComponent);
下面是一个使用 toStore()
函数的示例,注意该函数支持类的继承:
import { toStore, RawField } from '@haixing_hu/pinia-decorators';
import { Logger } from '@haixing_hu/logging';
import dayjs from 'dayjs';
class BaseUserStore {
id = '';
username = '';
password = '';
nickname = '';
token = {
value: 'token-value',
expired: 1000,
};
get age() {
throw new Error('This getter will be overridden by subclass');
}
setNickname(nickname) {
this.nickname = nickname;
}
login() {
throw new Error('This function will be overridden by subclass');
}
}
class UserStore extends BaseUserStore { // support class inheritance
avatar = '';
birthday = '';
@RawField
logger = Logger.getLogger('store.user'); // this field is marked as raw field
get age() { // override the super class getter
return dayjs().diff(this.birthday, 'year');
}
setAvatar(avatar) {
this.avatar = avatar;
}
updatePassword(password) {
this.password = newPassword;
return api.updatePassword(this.username, newPassword);
}
login() { // override the super class method
this.logger.info('Logging in as:', this.username);
return api.login(this.username, this.password);
}
}
export default toStore('user', UserStore);
以上例子定义了一个名为 user
的 Pinia 存储,它等价于以下代码:
import { defineStore } from 'pinia';
import { markRaw } from 'vue';
const useUserStore = defineStore('user', {
state: () => ({
id: '',
username: '',
password: '',
nickname: '',
token: {
value: 'token-value',
expired: 1000,
},
avatar: '',
birthday: '',
logger: markRaw(Logger.getLogger('store.user')),
}),
getters: {
age: (state) => dayjs().diff(state.birthday, 'year'),
},
actions: {
setNickname(nickname) {
this.nickname = nickname;
},
setAvatar(avatar) {
this.avatar = avatar;
},
updatePassword(newPassword) {
this.password = newPassword;
return api.updatePassword(this.username, newPassword);
},
login() {
this.logger.info('Logging in as:', this.username);
return api.login(this.username, this.password);
},
},
});
export default useUserStore;
我们可以按如下方式在 Vue 组件中使用 UserStore
:
<template>
<div>
<div>Username: {{ username }}</div>
<div>Nickname: {{ nickname }}</div>
<div>Age: {{ age }}</div>
<div>Avatar: <img :src="avatar" /></div>
<button @click="setNickname('new-nickname')">Set Nickname</button>
<button @click="avatar = 'new-avatar.png'">Set Avatar</button>
<button @click="updatePassword('new-password')">Change Password</button>
<button @click="login()">Login</button>
</div>
</template>
<script>
import { Component, toVue } from '@haixing_hu/vue3-class-component';
import { State, Getter, Action } from '@haixing_hu/pinia-decorators';
import UserStore from 'src/stores/user';
@Component
class UserPage {
@State(UserStore)
username;
@State(UserStore)
nickname;
@WritableState(UserStore)
avatar;
@Getter(UserStore)
age;
@Action(UserStore)
setNickname;
@Action(UserStore)
updatePassword;
@Action(UserStore)
login;
}
export default toVue(UserPage);
</script>
有关更多详细信息,请查看以下演示项目:
贡献
如果你发现任何问题或有改进建议,请随时在 GitHub 仓库 中提出问题或提交请求。
我们欢迎你的贡献和反馈!
许可证
pinia-decorator
遵循 Apache 2.0 许可证分发。
请查看 LICENSE 文件以获取更多详细信息。