npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

puppet-vue3

v0.1.0

Published

puppet-vue3

Downloads

6

Readme

puppet-vue3

一款轻量级的 Vue3 状态管理库,基于 Typescript + Vue3 响应式系统实现。

安装

  1. 安装依赖包
npm i -S puppet-vue3
  1. 在tsconfig.json中配置如下属性:
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"useDefineForClassFields": false,

如何创建一个 Store?

Puppet 是基于来实现的 Store,你可以在项目中的任何地方创建一个类,作为你的 Store,至于你想让这个 Store 是单例的还是多例的(一般是单例的),由你自己来决定。

如何创建一个 State?

你可以通过 @State() 装饰器来定义你的 State,被装饰的对象为 Store 中的成员变量,你可以通过@State()装饰器在一个 Store 中定义多个 State。当然,我们推荐您通过 private 访问修饰符将 State 设为私有的,再定义其 get 访问器,让外界通过 get 访问器访问你的 State。

export class ExampleStore {
    @State()
    private nameState = 'Zhangsan';

    @State()
    private dateOfBirthState = {
        year: 1999,
        month: 1,
        day: 10
    };

    get name(): string {
        return this.nameState;
    }

    get dateOfBirth(): DateOfBirth {
        return this.dateOfBirthState;
    }
}

通过这种方式得到的 State 是双向数据流的,你可以使用 Puppet 中的 @Freezer() 装饰器,得到一个单向数据流的 State!

@Freezer()
get dateOfBirth(): DateOfBirth {
    return this.dateOfBirthState;
}

对于基本类型的 State,因为没有 set 访问器,本身就是单向的,无需用该装饰器装饰。

get name(): string {
    return this.nameState;
}

如何使用 State?

如果你的项目没有依赖注入工具的话,推荐你建一个或多个 ts 文件,来保存你的 state 实例。

export const exampleStore = new ExampleStore();
export const exampleStore2 = new ExampleStore2();
export const exampleStore3 = new ExampleStore3();

在 vue 文件中,如果你的 State 是对象类型,如上面 ExampleStore 中的 dateOfBirth,Puppet 允许你对第一层解构来使用,而不失响应性。当然你不可以将这个 State 再赋其他类型的值。如:原 State 是对象类型,为其赋基本类型的值、原 State 是非数组类型的对象,将其赋数组类型的对象。

<template>
    <ul>
        <li>Date Of Birth</li>
        <li>Year: {{ dateOfBirth.year }}</li>
        <li>Month: {{ dateOfBirth.month }}</li>
        <li>Day: {{ dateOfBirth.day }}</li>
    </ul>
</template>

<script lang="ts" setup>
import { exampleStore } from '@/stores';
const { dateOfBirth } = exampleStore;
</script>

如果你的 state 是基本类型,如上面 ExampleStore 中的 name,则不可以解构,你需要通过 exampleStore.name 来使用,否则会失去响应性。

<div>Name:{{ exampleStore.name }}</div>

如何更改 State?

在 Puppet 中没有像 Vuex 中 mutation、action 的概念,你可以在 Store 中定义普通的方法来改变该 Store 中的 State。

setName(newName: string): void {
    this.nameState = newName;
}

setDateOfBirth(newDateOfBirth: DateOfBirth): void {
    this.dateOfBirthState = newDateOfBirth;
}

setYearOfBirth(newYear: number): void {
    this.dateOfBirthState.year = newYear;
}

如何双向绑定 State?

如果你需要的场景是输入的值一旦改变,立即更新 State,则建议: 基本类型的 State:提供 set 访问器,直接在 vue 文件中双向绑定。 对象类型的 State:提供没有被@Freezer()装饰器装饰的 get 访问器,双向绑定 get 访问器返回的 State。

<ul>
    <li>Name: <input v-model="exampleStore.name" /></li>
    <li>Date Of Birth</li>
    <li>年:<input v-model="changeableDateOfBirth.year" /></li>
    <li>月:<input v-model="changeableDateOfBirth.month" /></li>
    <li>日:<input v-model="changeableDateOfBirth.day" /></li>
</ul>

set name(newName: string) {
    this.nameState = newName;
}

get name(): string {
    return this.nameState;
}

get changeableDateOfBirth(): DateOfBirth {
    return this.dateOfBirthState;
}

如果你需要的场景是输入值改变,在某一动作后,再更新 State,如提交表单,则建议使用 Puppet 提供的 @Shadow() 装饰器,通过该装饰器创建 State 或 State 的一部分的响应式副本,再在页面进行双向绑定。该装饰器有两个重载:

export function Shadow(shadowKey: string | symbol): PropertyDecorator;
export function Shadow<R extends Record<string | symbol, any>>(
    partialState: (stateHolder: any) => R,
    shadowKey: R extends any[] ? number : keyof R
): PropertyDecorator;

第一个重载的参数为,当前 Store 中你需要的 State 的 key。 第二个重载的参数为,partialState:当前 Store 中你需要的 State 中的对象的父对象; shadowKey:当前 Store 中你需要的 State 中的对象的 key。 使用方式如下:

@Shadow('name')
nameShadow: PuppetShadow<string>;

@Shadow((store: ExampleStore) => store.dateOfBirthState, 'month')
monthOfBirthStateShadow: PuppetShadow<number>;

返回的 PuppetShadow 类型对象是一个元组,第一个元素为,你需要的 State 或 State 的一部分的对象副本,并且是响应式的,如果这个副本是基本类型,则 Puppet 会通过 Vue3 的 ref 函数去创建并包装这个副本。 第二个元素为提交这个副本的函数,调用此函数后,Puppet 会将你更改后的副本覆盖到你的 State 中去。第三个元素为重置这个副本的函数,调用此函数后,将当前的副本重置到初始值或上一次提交的值。

<ul class="puppet-ul">
    <li>Year Of Birth:<input v-model="dateOfBirthShadow.year" /></li>
    <li><button @click="commitDateOfBirthShadow">Commit</button></li>
    <li><button @click="resetDateOfBirthShadow">Reset</button></li>
    <li>Month Of Birth:<input v-model="monthOfBirthShadow" /></li>
    <li><button @click="commitMonthOfBirthShadow">Commit</button></li>
    <li><button @click="resetMonthOfBirthShadow">Reset</button></li>
</ul>

const [dateOfBirthShadow, commitDateOfBirthShadow, resetDateOfBirthShadow] = exampleStore.dateOfBirthShadow;
const [monthOfBirthShadow, commitMonthOfBirthShadow, resetMonthOfBirthShadow] = exampleStore.monthOfBirthShadow;