typescript - Skapa en global butik med Vue 3 Composition API


Jag försöker skapa en global butik med enbart Vue 3 Composition API.

Hittills har jag experimenterat, och jag har läst mycket om hur man använder Composition API, men just nu vet jag inte hur man använder provide och inject.

Allt jag vet är att provide kommer att ha all data som kommer att skickas till en barnkomponent, så jag tänkte att jag borde importera store till main.ts. Och koden ser ut så här:

Detta är butiken (src/store/index.ts):

import { reactive, readonly } from "vue";

const state = reactive({
  fnacResults: [],
  interResults: [],
});

export default { state: readonly(state) };

Detta är main.ts:

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store/index";

createApp({ provide: { store }, }, App)
  .use(router)
  .mount("#app");

Och när föräldrakomponenten har datan, om jag använder inject, kommer jag att kunna få tillgång till all data i lagret. Men i mitt fall fungerar det inte. Jag har en känsla av att felet börjar när jag sätter provide i min main.ts-fil.

Har du försökt att skapa en global butik med Composition API med provide och inject?

Förresten, min komponentfil (src/views/Home.vue) ser ut så här:

<template>
  <div>{{ store.state.fnacResults }}</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  inject: ['store']
});
</script>

Svar #1

Applikations-API

Det första argumentet till createApp bör vara en komponentdefinition (vilket skulle vara App i ditt fall). Istället kan du använda app-instansens provide():

createApp(App).provide('store', store).mount('#app')

demo

Kompositions-API

Med Composition API kan du använda provide på detta sätt:

// Parent.vue
import { provide } from 'vue'
import store from '@/store'

export default {
  setup() {
    provide('store', store)
    //...
  }
}

Sedan i någon efterföljande komponent skulle du injicera det med:

// Child.vue
import { inject } from 'vue'

export default {
  setup() {
    const store = inject('store')

    return {
      results: store.state.interResults
    }
  }
}

Importera

Alternativt kan det vara enklare att bara importera butiken där du behöver den, och använda den direkt:

// Child.vue
import store from '@/store'

export default {
  setup() {
    return {
      results: store.state.interResults
    }
  }
}

Svar #2

Försök att tillhandahålla store i rotkomponenten App och använd den sedan i någon underkomponent:

export default {
   name:"App",
  provide: { store },

...

Hej komponent :

<template>
  <div>
    <ul>
      <li v-for="(item, i) in fnacResults" :key="i">{{ item }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  inject: ["store"],
  computed: {
    fnacResults() {
      return this.store.state.fnacResults;
    },
  },
  mounted() {
    console.log(this.store.state);
  },
};
</script>

<style>
</style>

LIVE DEMO

Relaterade artiklar