簡體   English   中英

在Vue JS中將數組子級更新為父級的正確方法是什么

[英]What is the correct way to update an array child to parent in Vue JS

因此,我正在學習Vue.js,經過一番努力,我(以某種方式)使以下代碼可以正常工作 我知道,如果它可以工作,那不是愚蠢的,但是盡管如此,我仍想尋求有關如何改進代碼的幫助,因為我懷疑自己是否采用了正確的方法。

以下代碼允許用戶通過單擊按鈕添加Item組件的多個實例。 將Item中名稱字段的輸入傳遞給對象,並將其插入到數組中,該數組將被發送回父組件。

我使用這種方法的主要問題是,在Item的所有實例之間共享items數組作為道具,這是不必要的。 但是,我無法提出其他解決方案,因為我只知道如何通過將其作為道具傳遞和更新來在組件之間共享數據。 我還讀到道具只能由父母來更新,所以我猜我也在違反那個規則。

有人可以教我更好的方法嗎?

母碼

<template>

    <div class="items">
         <div v-for="n in itemCount">
            <Item :count="n" :items="items"  />
         </div>
    </div>

    <button @click="addItem">Add item</button>

</template>

<script>
    import Item from './../components/Item'; //the child 

    export default {

        components: {
            Item
        },

        data() {
            return {
                itemCount: 1,
                items: [],
            }
        },

        methods: {
            addItem() {
                this.itemCount ++;
            }
        }

    }
</script>

兒童

<template>

    <div class="item">
        <label>Item name</label>
        <input type="text" v-model="name" @input="update(count)" />    
    </div>

</template>

<script>
    export default {

        props: ['items','count'],

        data() {
            return {
                name: '',
            }
        },

        methods: {

            createItem(index) {
                return {
                    index: index-1,
                    name: this.name,
                }
            },

            update(index) {
                const item = this.createItem(index);
                this.$set(this.items, index-1, item);
            },
        }
    }
</script>

您有理由對初始實施感到不舒服。 理想情況下,子組件不應對父組件承擔任何責任。 在這種情況下,子組件僅呈現<label><input>以便用戶輸入項目名稱。 它不應該知道或關心多個項目。 這是創建此類組件的一種方法。 它有效地定義了自己的模型,並將該模型簡單地反映到<input>

Vue.component('custom-item', {
  props: {
    value: String
  },
  template: `
    <div class="custom-item">
      <label>Item name</label>
      <input
        type="text"
        :value="value"
        @input="$emit('input', $event.target.value)"
      >
    </div>
  `
});

然后,父組件只是向子組件提供適當的v-model :(請注意,我已經將<button>移到了根元素內,因為模板不能包含多個直接子元素。)

Vue.component('custom-items', {
  data() {
    return {
      items: []
    };
  },
  methods: {
    addItem() {
      items.push({
        index: items.length,
        name: ""
      });
    }
  },
  template: `
    <div class="custom-items">
      <div v-for="item in items">
        <custom-item v-model="item.name"/>
      </div>
      <button @click="addItem">
        Add item
      </button>
    </div>
  `
});

該代碼對items對象使用相同的結構,但實際上似乎不太需要.index屬性,在這種情況下, items可能只是字符串數組而不是對象。

另外,除非您在樣式上做一些時髦的事情,否則實際上不需要在每個自定義項周圍使用<div>包裝器,因此為簡單起見,您可以放棄它:

    <div class="custom-items">
      <custom-item
        v-for="item in items"
        v-model="item.name"
      />
      <button @click="addItem">
        Add item
      </button>
    </div>

上面可能有一些錯別字,因為我尚未測試過,但我認為您可以理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM