问题
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.
回答1:
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.
回答2:
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>
来源:https://stackoverflow.com/questions/46440979/how-to-properly-pass-data-from-child-to-parent-and-parent-to-child-component