• Vue3 与依赖注入


    Vue3 与依赖注入

    本文写于 2021 年 2 月 19 日

    在 React 中,我们可以通过 context 与 useContext 实现单例、注入……等诸多特性。

    详细请看上一篇文章:如何利用 React Hooks 管理全局状态.

    例如:

    const SomeService = createContext(null);
    
    const useRootSomeService = () => {
      const [n, setN] = useState(0);
    
      const add = useCallback(() => {
        setN((number) => number + 1);
      }, []);
    
      return { n, setN };
    };
    
    const App: React.FC = () => {
      return (
        <SomeService.Provider value={useRootSomeService()}>
          <Apple />
        </SomeService>
      )
    };
    
    const Apple: React.FC = () => {
      const someService = useContext(SomeService)
    };
    

    那么 Vue3 可以吗?

    可以!!!只需要利用 Vue3 的 provide 与 inject API 即。

    创建一个 Service

    import { Ref, ref } from "vue";
    
    class ChatService {
      static INJECT_KEY: string;
    
      conversations: Ref<Conversation[]>;
    
      constructor() {
        this.conversations = ref([]);
      }
    }
    

    这样我们只需要在组件中实例化该 class,就可以拥有响应性的 conversations 属性了。

    但是我们不满足于如此,我们还想要在任何地方,都可以使用 const chatService = inject(ChatService); 来拿到服务的单例!

    provide/inject

    vue3 提供给我们的 provide API 可以在任意组件中使用:provide(key, variable);

    使用后该组件的自组件的任何位置都可以利用 inject API 拿到刚刚注入的变量:const v = inject(key);

    因此我们可以这么封装一下:

    import { provide as vueProvide, inject as vueInject } from "vue";
    
    export const createInjectKey = () => {
      const randomNumber = Math.round(Math.random() * 10 ** 8).toString();
      return randomKey;
    };
    
    interface ServiceType<T> {
      new (): T;
      INJECT_KEY: string;
    }
    
    export function provide<T>(Service: ServiceType<T>) {
      const key = createInjectKey();
      Service.INJECT_KEY = key;
      vueProvide(key, new Service());
    }
    
    export function inject<T>(Service: ServiceType<T>): T {
      const service = vueInject<T>(Service.INJECT_KEY);
      if (!service) {
        console.error("You have to provide service first!!!");
      }
      return service!;
    }
    

    这样一来,我们只需要写一个拥有 static INJECT_KEY 属性的 class,就可以在组件树顶端使用 provide(xxxService),然后再在任意位置调用 inject(xxxService) 来获取服务单例了!

    (完)

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    基于java容器注解---基于泛型的自动装配
    mininet+floodlight搭建sdn环境并创建简单topo
    Bean装配之@Autowired注解
    Linux常用命令
    Bean利用Resource接口获取资源的几种方式
    MYSQL分页优化查询
    MYSQL统计和识别重复值
    MYSQL统计和识别重复值
    MYSQL处理数据重复值
    MYSQL处理数据重复值
  • 原文地址:https://www.cnblogs.com/xhyccc/p/14414170.html
Copyright © 2020-2023  润新知