Rumah  >  Soal Jawab  >  teks badan

Isu dengan Vue.js 3 dan Pinia Getters

Saya beralih daripada Angular kepada Vue.js dan cuba memahami seni binanya. Saya kini terperangkap dengan masalah asas dan telah menggunakan banyak penyelesaian, tetapi saya benar-benar hanya melihat penyelesaian sementara.

Isu utama di sini ialah kerjasama antara Vue.js 3 dan Pinia. Pinia terdiri daripada Store, Getter dan Action. Kadang-kadang kami mempunyai objek yang sangat bersarang dalam Kedai dan kami hanya memerlukan bahagian tertentu daripadanya. Mencipta pengambil akan sesuai untuk ini, sebagai contoh, untuk mengeluarkan hanya sebahagian daripada objek yang saya perlukan.

Tetapi bagaimana jika saya mahu menukar betul-betul bahagian objek tersebut daripada templat? Harapan saya ialah data di kedai juga berubah. Tetapi oleh kerana getter adalah baca sahaja, ini tidak boleh dilakukan.

Bagaimana untuk meneruskan di sini?

Sudah tentu, saya ingin menunjukkan kepada anda satu contoh untuk menekankan penjelasan saya dengan beberapa latihan.

export const useGeneralStore = defineStore('general', {
  state: () => {
    return {
      roles: [],
      currentRole: 'basic',
    }
  },
  getters: {
    getElementsForCurrentRole: (state) => {
      let role = state.roles.find((role) => {
        return role.value == state.currentRole;
      });

      if (role) {
        return role.data;
      }
    }
  },
  actions: {}
})

Saya menggunakan objek yang sangat bersarang di sini roles 创建一个商店。在我在 v-for 模板中使用的 getter getElementsForCurrentRole di mana saya hanya memerlukan elemen tertentu.

Untuk memudahkan pemahaman semua orang, saya juga akan menyiarkan kod templat di sini:

<template>
  <div class="element-container">
    <div v-for="cat of elementCategories" :key="cat">
      <h4>{{cat}}</h4>
      <draggable 
        v-model="getElementsForCurrentRole" 
        :group="cat"
        @end="save" 
        item-key="name">
        <template #item="{element}">
          <n-card v-if="element.category == cat" class="element" :class="element.name" :title="element.name" size="small" header-style="{titleFontSizeSmall: 8px}" hoverable>
            <n-switch v-model:value="element.active" @update:value="save(element)" size="small" />
          </n-card>
        </template>
      </draggable>
    </div>
  </div>
</template>

<script setup>
  import { NCard, NSwitch, useMessage } from 'naive-ui';
  import draggable from 'vuedraggable'
  import { usePermissionsStore } from '@/stores/permissions';
  import { storeToRefs } from 'pinia';

  const permissionsStore = usePermissionsStore();
  const { getElementsForCurrentRole } = storeToRefs(permissionsStore);  

  const elementCategories = ['basic', 'professional'];
</script>

Gunakan storeToRefs 函数后,我循环遍历 getElementsForCurrentRole getter,以使数据具有反应性。我的问题是数据可能只是部分反应性的。例如,如果我更改 Switch 元素的值,则商店更新成功。这有效。但是,我似乎无法访问正在循环的数组的顺序。一旦我通过拖放更改顺序,我就会收到消息:写入操作失败:计算值是只读 seperti yang dinyatakan dalam dokumentasi.

Saya tidak faham ini, saya tidak boleh memahaminya.

Sebagai penyelesaian, saya sedang mengira indeks lama dan baharu rekod dalam tatasusunan selepas menyeret berdasarkan acara dan mengemas kini storan secara manual. Tetapi itu tidak boleh menjadi tujuan di sebaliknya. Adakah saya pada asasnya salah faham sesuatu dalam seni bina? Bagaimanakah orang akan menangani keadaan sedemikian?

P粉668019339P粉668019339350 hari yang lalu647

membalas semua(1)saya akan balas

  • P粉034571623

    P粉0345716232023-11-04 15:30:00

    Anda menggunakan pengambil. Getter ialah harta baca sahaja. Untuk mengemas kini nilai dalam mana-mana kedai pinia, anda mesti membuat tindakan. Dan anda menggunakan v-model yang mengikat dan menulis apabila nilai berubah. Oleh itu, ia boleh dibaca menggunakan getter, tetapi tidak ditulis. Terdapat beberapa kemungkinan untuk situasi anda. Salah satunya ialah mencipta sifat dan operasi yang dikira. Macam ni

    actions: {
      updateRole(newRole) {
        this.currentRole = newRole
    }

    Dan sifat yang dikira dalam komponen:

    const myComputed = computed({
      get: () => getElementsForCurrentRole.value,
      set: (val) => updateRole(val),
    })

    balas
    0
  • Batalbalas