# vue3 使用 provide/inject 代替 vuex

感觉 vuex 使用起来跟 redux 一样烦, vuex3 中 provide/inject 的写法可能会比较好, 尝试使用替换状态管理方案

参考文章

# 使用脚手架创建项目

vue create my-app

# 构建 store

新建src/store/modules/counter.js. 一个简单的计数器状态管理

import { provide, inject, ref, reactive, readonly } from "vue";

const COUNTER = Symbol();

const delay = (ms = 1000) =>
  new Promise((r) => {
    const t = setTimeout(() => {
      clearTimeout(t);
      r();
    }, ms);
  });

export function useCounterProvider() {
  const count = ref(10);
  const state = reactive({ count: 0 });

  const add = () => {
    count.value++;
    state.count++;
  };

  const sub = async () => {
    await delay();
    count.value--;
    state.count--;
  };

  provide(COUNTER, readonly({ state, count, add, sub }));
}

export function useCounter() {
  return inject(COUNTER);
}

新建src/store/index.js. 模块汇总文件

import { useCounterProvider, useCounter } from "./modules/counter";

function useStore() {
  useCounterProvider();
}

export { useStore, useCounter };

# 挂载 store

src/App.vue

import { useStore } from "./store/index";

export default {
  name: "App",
  components: {
    HelloWorld,
  },

  setup() {
    useStore();
  },
};

# 在子组件中注入

<template>
  <p>count {{ counter.count }}</p>
  <p>count {{ counter.state.count }}</p>

  <button @click="counter.add">add</button>
  <button @click="counter.sub">sub</button>
</template>
import { useCounter } from "@/store/index";

export default {
  name: "HelloWorld",
  setup() {
    // 不能使用扩展符展开
    const counter = useCounter();

    return { counter };
  },
};
Last Updated: 12/10/2020, 6:21:38 PM