【问题标题】:Vue.js - emit to update array not workingVue.js - 发出更新数组不起作用
【发布时间】:2018-08-05 13:34:59
【问题描述】:

我有两个组件:父级和子级。 Parent 有一个 cars 数组, Child 应该将对象推送到 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: []
  }
 }
}

我的孩子组件:

<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 的方式有问题和/或我发出的方式不正确。有人可以帮忙吗?提前致谢!

【问题讨论】:

    标签: javascript vue.js emit


    【解决方案1】:

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

    首先我们需要了解v-model在默认情况下是如何作用于自定义组件的。

    当使用文本input(包括emailnumber等类型)或textarea时,v-model="varName"等价于:value="varName" @input="e =&gt; varName = e.target.value"。这意味着在每次更新输入varName 更新为输入值后,输入值设置为varName。一个普通的选择元素也会这样,虽然多选会有所不同。

    现在我们需要了解,

    v-model 如何在组件上工作?

    由于 Vue 不知道您的组件应该如何工作,或者如果它试图替代某种类型的输入,它会以相同的方式对待所有组件 v-model。它实际上与文本输入的工作方式完全相同,除了在事件处理程序中,它不期望将事件对象传递给它,而是期望将值直接传递给它。所以……

    &lt;my-custom-component v-model="myProperty" /&gt;

    ……和……是一回事

    &lt;my-custom-component :value="myProperty" @input="val =&gt; myProperty = val" /&gt;

    所以当你应用这种方法时。您必须收到value 作为道具。并确保你 $emit 的名字是 input

    现在你可以在这个阶段问我,你做错了什么?

    好的,看like code @input="val =&gt; 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: []
      }
     }
    }
    

    `

    子组件:

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

    您实际上可以通过多种方式解决它。

    第二种方法,

    家长:

    <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')
                }
            }
        }
    

    【讨论】:

    【解决方案2】:

    可以触发更新props中传输值的事件

    在父级中

    <my-component :is-open.sync="isOpen" />
    

    在我的组件中

    this.$emit('update:isOpen', true)
    

    【讨论】:

      猜你喜欢
      • 2021-06-12
      • 2017-02-09
      • 2017-06-28
      • 2019-07-21
      • 2016-12-10
      • 1970-01-01
      • 2018-08-16
      • 2016-06-09
      • 1970-01-01
      相关资源
      最近更新 更多