Vue.js-发射更新数组不起作用

Joh*_*son 5 javascript emit vue.js

我有两个部分:父母和孩子。父级有一个cars子级数组,应该将对象推入该cars数组。我的问题是我的Child组件变成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: []
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

我的孩子组件:

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

export default {
    methods: {
        addCar() {
            this.$emit("input", { model: "some car model" })
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

预期成绩:

cars 更新并成为 [{ model: "some car model"}, { model: "some car model"}, etc...]

实际结果:

cars 成为一个对象 {model: "some car model"}

这是我的小提琴:

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

我认为v-model子组件上使用的方式和/或发出的方式不正确。有人可以帮忙吗?提前致谢!

小智 9

让我们讨论一下为什么您没有得到正确的结果。然后我们讨论解决此问题的其他方法。

首先,我们需要了解v-model默认情况下如何在自定义组件上工作。

当使用文本input(包括类型,例如emailnumber等)或textareav-model="varName"等价于:value="varName" @input="e => varName = e.target.value"。这意味着varName在每次对输入varName的更新都更新为输入的值之后,将输入的值设置为。普通选择元素也将像这样,尽管多次选择将有所不同。

现在我们需要了解

v模型如何在组件上工作?

由于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" })

您用一个对象更新您的父值。因此,您Array使用进行了更新Object

让我们解决完整的问题。

父组件:

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

export default {
 data: function() {
  return {
    cars: []
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

`

子组件:

<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"}))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您实际上可以用几种方法解决它。

第二种方法

上级:

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

export default {
 data: function() {
  return {
    cars: []
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

儿童:

<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" })
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后方法:

上级:

    <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" })
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

儿童:

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

    export default {
        methods: {
            update() {
                this.$emit('update')
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)