How to properly pass data from child to parent and

2019-07-30 22:40发布

First of all, this is my current structure

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

My Scenario

1) At initial state, i have to get value from Child's Text Input and store it in local. (Child to Parent) 2) After browser refresh, i will check for any local data, if it exsist, i have to populate child's value (Parent to Child)

The error with current structure

whenever i type or select something it triggers this error

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"

so how to avoid this error? how to properly implement this structure, so that i can reuse this component wherever i want.

2条回答
We Are One
2楼-- · 2019-07-30 22:49

You are using props with v-model. Props will be overridden when the parent component is re-renders.

Use data with v-model and set the initial values from the props:

CHILD COMPONENT

// 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
  }
}

It might be worth changing your props to be called initialSelectedItem and initialCompVal instead, and then have the data properties called selectedItem and compVal.

查看更多
Viruses.
3楼-- · 2019-07-30 23:08

You could use a locally bound setter then pass it to the child. The child has then a method to set property of the parent.

Here's an example.

<!-- 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>
查看更多
登录 后发表回答