Inheritance/Shared Operations and Getters in Pinia
P粉662614213
P粉662614213 2023-12-22 13:50:12
0
2
516

Saya mempunyai beberapa kedai Pinia yang sepatutnya berkongsi satu set operasi dan pengambil, tetapi saya tidak pasti bagaimana untuk mencapainya dengan cekap.

Saya sedang membina aplikasi yang membolehkan pengguna mengurus pelbagai media (buku, filem, rancangan TV, dll.). Cara yang saya fikirkan pada masa ini ialah untuk mempunyai kedai untuk setiap jenis media, seperti Kedai Buku, MovieStore, dsb. Banyak pengambil dan operasi (seperti countdeleteOne) adalah betul-betul sama antara kedai yang berbeza ini.

Bagaimana untuk melaksanakan DRY di sini? Contoh dalam dokumentasi Pinia menumpukan pada penggunaan semula tindakan dan pengambil dalam kedai lain, tetapi saya tidak fikir ini menangani sepenuhnya kes penggunaan saya yang mewarisi secara langsung satu set pengambil dan penetap.

Adakah pendekatan pewarisan yang saya cuba di sini adalah anti-corak?

P粉662614213
P粉662614213

membalas semua(2)
P粉420958692

Jika anda mahu beberapa fungsi dikongsi di bukan semua kedai, anda boleh menggunakan boleh gubah.

Anda boleh mencipta fungsi boleh gubah yang berasingan dan menghantar sebahagian daripada contoh kedai ke dalamnya.

Saya buat contoh untuk anda di kotakdandbox.

Berikut ialah contoh ringkas codesandbox:

common.ts

import { computed, Ref, ref } from "vue";

export function useCommon(initValue: number) {
    const _value = ref<number>(initValue);

    function increment() {
        _value.value++;
    }

    function someProcessing() {
        // ... some code here
    }

    return {
        counter,

        increment,
        someProcessing,
    };
}

Kemudian di mana-mana kedai anda boleh menggunakannya seperti ini:

fooStore.ts

export const useFooStore = defineStore('foo', () => {
    const state = ref<string>('foo');

    const { counter, increment, someProcessing } = useCounter(0);

    return {
        state,

        counter,
        increment,
        someProcessing,
    }
}

Dengan cara ini anda boleh mengarang sebarang fungsi, objek, dsb. dalam mana-mana storan atau dalam mana-mana komponen.

P粉449281068

Ini boleh dicapai menggunakan pemalam docs

Contoh filem:

Anda mempunyai berbilang kedai, setiap negeri menggunakan skema penamaan yang dikongsi:

  • Item: Item entiti tunggal (butiran filem tunggal)
  • koleksi: koleksi projek (koleksi semua filem)

Setiap kedai akan mempunyai operasi CRUD yang sama, cuma URL berubah

  • getCollection: Dapatkan senarai item daripada API dan tetapkan respons kepada koleksi (https://url.com/movies a>)
  • getItem: Dapatkan satu item daripada API dan tetapkan respons kepada item tersebut (https://url.com/movies/ id)
  • handleError: Tunjukkan amaran dengan mesej ralat kepada pengguna

Buat pemalam:

function BaseStorePlugin () {
    return {
        collection: [],
        item: {},
        getCollection: function (url) {
            api.get(url)
                .then((response) => {
                    this.collection = response.data;
                })
                .catch((error) => {
                    this.handleError(error);
                });
        },
        getItem: function (url) {
            api.get(url)
                .then((response) => {
                    this.item = response.data;
                })
                .catch((error) => {
                    this.handleError(error);
                });
        },
        handleError: function (error) {
            window.alert(error);
        },
    };
}

Sediakan pemalam untuk Pinia:

const pinia = createPinia();

pinia.use(BaseStorePlugin);

Contoh movieStore.js (menggunakan tindakan dan keadaan yang dikongsi)

import { defineStore } from 'pinia';
import { api } from 'src/boot/axios';

export const useMovieStore = defineStore({
    id: 'movie',
    state: () => ({
        movieSpecificStateObject: {},
    }),
    actions: {
        movieSpecificAction (url) {
            console.log(this.item);
            api.get(url)
                .then((response) => {
                    // handle response
                })
                .catch((error) => {
                    this.handleError(error);
                });
        },
    },
});

Contoh penggunaan dalam komponen

<template>
    <div
        v-for="movie in movieStore.collection"
        :key="movie.id"
    >
        <div>
            {{ movie.name }}
        </div>
    </div>
</template>

<script setup>
import { onMounted } from 'vue';
import { useMovieStore } from 'src/stores/movieStore.js';
const movieStore = useMovieStore();

onMounted(() => {
    movieStore.readCollection('http://url.com/movies');
});
</script>

Editor: 1

Jika anda menghantar konteks ke dalam pemalam, anda boleh mengakses kedai dan pilihan yang dihantar ke dalamnya, yang mana anda boleh menyemak ID kedai dan hanya mengembalikan kedai tertentu seperti yang ditunjukkan di bawah

function BaseStorePlugin (context) {
  const allowedStores = ['movie', 'album'];

  if (allowedStores.includes(context.store.$id)) {
    return {
      collection: [],
      getCollection: function () {
        const fakeCollection = Array.from({length: 10}, () => Math.floor(Math.random() * 40));
        fakeCollection.forEach((item) => {
          this.collection.push({
            id: item,
            name: `name${item}`
          });
        });
      },
    };
  };
}

Saya mencipta contoh yang sangat asas menggunakan 3 kedai, cek di atas tersedia dalam kotak pasir kod di sini

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan