web-dev-qa-db-ja.com

Vue.js-配列を更新するために発行するが機能しない

親と子の2つのコンポーネントがあります。親にはcarsの配列があり、子にはcars配列のプッシュオブジェクトが想定されています。私の問題は、子コンポーネントがオブジェクトをcars配列にプッシュするのではなく、carsをオブジェクトに変換することです。私の親コンポーネント:

<template>
   <child v-model="cars"></child>
    <ul>
      <li v-for="car in cars">
         {{ car.model }}
      </li>
    </ul>
</template>

export default {
 data: function() {
  return {
    cars: []
  }
 }
}

マイチャイルドコンポーネント:

<template>
    <div>
        <button type="button" @click="addCar()">Add Car</button>
    </div>
</template>

export default {
    methods: {
        addCar() {
            this.$emit("input", { model: "some car model" })
        }
    }
}

推測される結果:

carsが更新され、[{ model: "some car model"}, { model: "some car model"}, etc...]になります

実績:

carsはオブジェクトになります{model: "some car model"}

これが私のフィドルです:

https://jsfiddle.net/t121ufk5/529/

子コンポーネントでv-modelを使用している方法に問題があるか、発行している方法が正しくないと思います。誰かが助けることができますか?前もって感謝します!

5
John Grayson

適切な結果が得られない理由について説明し、次にこの問題を解決するための他のアプローチについて説明します。

まず、v-modelがデフォルトでカスタムコンポーネントでどのように機能するかを理解する必要があります。

テキストinputemailnumberなどのタイプを含む)またはtextareaを使用する場合、v-model="varName":value="varName" @input="e => varName = e.target.value"と同等です。これは、入力varNameが入力の値に更新されるたびに、入力の値がvarNameに設定されることを意味します。複数の選択は異なりますが、通常の選択要素もこのように機能します。

今、私たちは理解する必要があります、

v-modelはコンポーネントでどのように機能しますか?

Vueは、コンポーネントがどのように機能するかを知らないため、または特定のタイプの入力の代わりとして機能しようとしている場合、v-modelに関してすべてのコンポーネントを同じように扱います。実際には、テキスト入力の場合とまったく同じように機能しますが、イベントハンドラーでは、イベントオブジェクトが渡されることを期待せず、値が直接渡されることを期待します。したがって…

<my-custom-component v-model="myProperty" />

…と同じです…

<my-custom-component :value="myProperty" @input="val => myProperty = val" />

したがって、このアプローチを適用する場合。小道具としてvalueを受け取る必要があります。 $emitの名前がinputであることを確認してください。

今、あなたはこの段階で私に尋ねることができます、あなたは何を間違っていますか?

わかりました、コードのように見てください@input="val => myProperty = val"

新しい値を$emitするとき。このnewValueは、更新したい親の値を更新します。

これがあなたのコードthis.$emit("input", { model: "some car model" })です。

親の値をオブジェクトで更新します。したがって、ArrayObjectで更新されます。

問題全体を解決しましょう。

親コンポーネント: `

<template>
   <child v-model="cars"></child>
    <ul>
      <li v-for="car in cars">
         {{ car.model }}
      </li>
    </ul>
</template>

export default {
 data: function() {
  return {
    cars: []
  }
 }
}

`

子コンポーネント:

<template>
    <div>
        <button type="button" @click="addCar()">Add Car</button>
    </div>
</template>

export default {
    props: ['value']
    methods: {
        addCar() {
            this.$emit("input", this.value.concat({model: "some car model"}))
        }
    }
}

あなたは実際にそれをいくつかの方法で解決することができます。

2番目のアプローチ、

親:

<template>
   <child :cars="cars"></child>
    <ul>
      <li v-for="car in cars">
         {{ car.model }}
      </li>
    </ul>
</template>

export default {
 data: function() {
  return {
    cars: []
  }
 }
}

子:

<template>
    <div>
        <button type="button" @click="addCar">Add Car</button>
    </div>
</template>

export default {
    props: {
       cars: {
          type: Array,
          default:[]
       }
    },
    methods: {
        addCar() {
            this.cars.Push({ model: "some car model" })
        }
    }
}

最後のアプローチ:

親:

    <template>
        <child @update="addCar"></child>
            <ul>
                <li v-for="car in cars">
                    {{ car.model }}
                </li>
            </ul>
    </template>

    export default {
        data() {
            return {
                cars: []
            }
        }
   },
   methods: {
      addCar() {
           this.cars.Push({ model: "some car model" })
      }
   }
}

子:

 <template>
     <div>
        <button type="button" @click="update">Add Car</button>
     </div>
    </template>

    export default {
        methods: {
            update() {
                this.$emit('update')
            }
        }
    }
9
HB Shifat