如何正确地将数据从子节点传递到父节点,父节点传递给子组件?

时间:2017-09-27 06:34:08

标签: vue.js vuejs2 vue-component

首先,这是我目前的结构

CHILD COMPONENT

// HTML
<v-select
 v-bind:items="selectItems"
 v-model="selectedItem"
 label="Category"
 item-value="text"
></v-select>
<v-text-field
 label="Enter Value"
 type="number"
 v-model="compVal"
></v-text-field>

// JS
props: {
 selectItems: {
  type: Array,
  required: true
 },
 selectedItem: {
  type: String
 },
 compVal: {
  type: Number
 },
}

PARENT COMPONENT

// HTML

<component :selecItems="selectOneItems" :selectedItem="selectOneItem" 
:compVal="compOneVal"></component>

<component :selecItems="selectTwoItems" :selectedItem="selectTwoItem" 
:compVal="compTwoVal"></component>

// JS
data () {
 return {
  selectOneItems: [someArray],
  selectedOneItem: null,
  compOneVal: 0,
  selectTwoItems: [someArray],
  selectedTwoItem: null,
  compTwoVal: 0
 }
}

我的情景

1)在初始状态下,我必须从Child的文本输入中获取值并将其存储在本地。 (孩子到父母) 2)浏览器刷新后,我将检查是否存在任何本地数据,如果它存在,我必须填充子项的值(Parent to Child)

当前结构的错误

每当我键入或选择某些内容时,都会触发此错误

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "compOneValue"

那么如何避免这个错误呢?如何正确实现这个结构,以便我可以在任何我想要的地方重用这个组件。

2 个答案:

答案 0 :(得分:2)

您正在 v-model 中使用道具。重新渲染父组件时,将覆盖道具。

数据 v-model 一起使用,并设置道具的初始值:

儿童成分

// HTML
<v-select
  v-bind:items="selectItems"
  v-model="selectedItemModel"
  label="Category"
  item-value="text"
></v-select>
<v-text-field
  label="Enter Value"
  type="number"
  v-model="compValModel"
></v-text-field>

// JS
props: {
  selectItems: {
    type: Array,
    required: true
  },
  selectedItem: {
    type: String
  },
  compVal: {
    type: Number
  },
},

data: function() {
  return {
    selectedItemModel: this.selectedItem,
    compValModel: this.compVal
  }
}

可能值得将您的道具更改为 initialSelectedItem initialCompVal ,然后将数据属性称为 selectedItem compVal

答案 1 :(得分:-1)

您可以使用本地绑定的二传手,然后将其传递给孩子。然后,孩子可以使用一种方法来设置父母的属性。

这是一个例子。

<!-- Component.vue -->

<template>
  <div class="login">
    {{ property }}
    <button v-on:click="setProperty('Something')">
    </button>
    <router-view/>
  </div>
</template>

<script>
const setProperty = (propertyValue) => {
  this.property = propertyValue
}

export default {
  name: 'Login',
  data () {
    return {
      // The 'bind(this)' is crucial since otherwise
      // 'this' will refer to the context of the caller
      // instead of what it is in this context.
      setProperty: setProperty.bind(this),
      property: 'Not something'
    }
  }
}
</script>