1.2.2 • Published 9 months ago

micro-reactive-cli v1.2.2

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

MICRO REACTIVE CLI

简介

micro-reactive cli

本地快速开始

# install micro-reactive-cli globally
pnpm i -g micro-reactive-cli
# create project
micro create my-app
# enter project
cd my-app
# install dependencies
pnpm i
# run dev
pnpm dev

模板

用于全局状态管理 (microx store)

  • options
/* options */
export const store = defineStore({
  id: "user",
  state: {
    count: 1,
  },
  getters: {
    double() {
      return this.count() * 2;
    },
    message() {
      return `double const is ${this.double()}`;
    },
  },
  actions: {
    increase(value: number = 1) {
      this.count(this.count() + value);
    },
  },
});
  • setup
/* setup */
import { defineStore } from "micro-reactive";

export const store = defineStore((ctx) => ({
  id: "user",
  state: {
    count: 1,
  },
  getters: {
    double: () => ctx.count() * 2,
    message: () => `double const is ${ctx.double()}`,
  },
  actions: {
    increase: (value: number = 1) => {
      ctx.count(ctx.count() + value);
    },
  },
}));
  • module
/* module */
import { useComputed, useMemo, useReactive } from "micro-reactive";

export const count = useReactive(0);
export const double = useMemo(() => count() * 2);
export function increase() {
  count(count() + 1);
}

solid js 中运行 (with solid js)

/* micro-counter.tsx */
import { useReactive } from "micro-reactive";

export default function Counter() {
  const count = useReactive(0);
  // 自增
  const increase = () => count(count() + 1);
  return (
    <button id="counter" type="button" onClick={increase}>
      count is {count()}
    </button>
  );
}
/* vite.config.ts */
import { defineConfig } from "vite";
import solidPlugin from "vite-plugin-solid";
// 自定义插件,在代码中嵌入 useEffect,收集依赖
import TrackEffect from "./plugins/vite-plugin-track-effect";

export default defineConfig({
  plugins: [solidPlugin(), TrackEffect()],
});
/* vite-plugin-track-effect.ts */
// 使用 useEffect 收集组件更新方法
const fileRegex = /\.(cjs|mjs|js|ts)/;
const funcRegex = /function updateComputation/;
// 导入
const importUseEffect = `import { useEffect } from "micro-reactive";`;
// 替换
const hackUpdateComputation = `
const update = updateComputation
updateComputation = function (node) {
  useEffect(() => update.call(this, node));
}`;
export default function TrackEffect() {
  return {
    name: "track-effect",
    transform(src: string, id: string) {
      if (fileRegex.test(id) && funcRegex.test(src)) {
        return { code: importUseEffect + src + hackUpdateComputation };
      }
    },
  };
}

vue3 中运行 (with vue3)

/* MicroCounter.vue */
<script setup lang="ts">
import { useReactive } from "micro-reactive";

const count = useReactive(0);
</script>

<template>
  <button type="button" @click="count(count() + 1)">
    count is {{ count() }}
  </button>
</template>
/* main.ts 中添加以下代码 */
import { ReactiveEffect } from "vue";
import { useEffect } from "micro-reactive";

// hack ReactiveEffect
const hackRun = ReactiveEffect.prototype.run;
ReactiveEffect.prototype.run = function () {
  return useEffect(() => hackRun.call(this));
};

react 中运行 (with react)

import { useComputed, useReactive } from "micro-reactive";
// 引入 hack
import { defineState } from "../hacks/defineState";

export default function Counter() {
  // useReactive 声明变量需写在 defineState 中
  const [count] = defineState(() => [useReactive(0)]);
  // 只读计算属性
  const double = () => count() * 2;

  return (
    <button onClick={() => count(count() + 1)}>
      double count is {double()}
    </button>
  );
}
/* defineState.ts */
import { useEffect } from "micro-reactive";
import { useState } from "react";

const stateMap = new WeakMap();

export function defineState<T extends {} | []>(defineReactive: () => T): T {
  const setter = useState({})[1];
  if (!setter) throw new Error("setter is empty");
  if (stateMap.has(setter)) {
    return stateMap.get(setter);
  }
  const state = useEffect(() => {
    setter({});
    if (stateMap.has(setter)) {
      return stateMap.get(setter);
    }
    const ret = defineReactive();
    for (const key in ret) {
      if (typeof ret[key] === "function") {
        (ret[key] as Function)();
      }
    }
    return ret;
  });
  stateMap.set(setter, state);
  return state;
}
1.2.2

9 months ago

1.2.1

9 months ago

1.2.0

9 months ago

1.1.0

9 months ago

1.0.2

9 months ago

1.0.1

9 months ago

1.0.0

9 months ago