Vue3 and dependency injection

Time:2021-9-23

Vue3 and dependency injection

This article was written on February 19, 2021

In react, we can implement singleton, injection… And many other features through context and usecontext.

See the previous article for details:How to manage global state with react hooks.

For example:

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 (
    
      
    
  )
};

const Apple: React.FC = () => {
  const someService = useContext(SomeService)
};

Is vue3 OK?

sure!!! You only need to use vue3’s provide and inject APIs, that is.

Create a service

import { Ref, ref } from "vue";

class ChatService {
  static INJECT_KEY: string;

  conversations: Ref;

  constructor() {
    this.conversations = ref([]);
  }
}

In this way, we only need to instantiate the class in the component to have the responsive conversations attribute.

But we are not satisfied with this. We also want to use it anywhereconst chatService = inject(ChatService);To get a single example of service!

provide/inject

The provide API provided by vue3 can be used in any component:provide(key, variable);

After use, you can use the inject API to get the newly injected variables from any part of the component:const v = inject(key);

Therefore, we can encapsulate it as follows:

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 {
  new (): T;
  INJECT_KEY: string;
}

export function provide(Service: ServiceType) {
  const key = createInjectKey();
  Service.INJECT_KEY = key;
  vueProvide(key, new Service());
}

export function inject(Service: ServiceType): T {
  const service = vueInject(Service.INJECT_KEY);
  if (!service) {
    console.error("You have to provide service first!!!");
  }
  return service!;
}

In this way, we only need to write one with static injection_ The class of the key attribute can be used at the top of the component treeprovide(xxxService), and then called anywhereinject(xxxService)To get the service order!

(end)