I would like to pass data from my parent to child component and bind data to a input field through v-model to display data from my api call in parent component. But it seems to be problem when binding to input field i get this error message:
Unexpected mutation of "data" prop.eslintvue/no-mutating-props
Partent Component
<script lang="ts">
import { defineComponent,ref } from 'vue';
import axios from 'axios'
import ChildComponent from '../components/ChildComponent.vue';
export default defineComponent({
Component: { ChildComponent },
name: 'IndexPage',
setup() {
return {
fixed: ref(false),
data: []
};
},
mounted() {
this.getData();
},
methods: {
getData() {
axios.get('/api/Hotel/' 2).then((response) => {
this.data = response.data;
this.fixed = true,
console.log(this.data);
});
}
},
components: { ChildComponent }
});
</script>
Child Component
<template>
<main>
<q-card >
<q-card-section>
<div >Terms of Agreement</div>
<div >
<div style="max-width: 300px">
<div>
<q-input filled v-model="data.message" label="Filled" />
</div>
</div>
</div>
</q-card-section>
<q-separator />
<q-separator />
<q-card-actions align="right">
<q-btn flat label="Decline" color="primary" v-close-popup />
<q-btn flat label="Accept" color="primary" v-close-popup />
</q-card-actions>
</q-card>
</main>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
props:['data'],
name: 'ChildComponent',
setup() {
return {
text: ref(''),
};
},
});
</script>
I have tried this to make mounted methods in my child components like this:
<div>
<q-input filled v-model="dataIn.message" label="Filled" />
</div>
export default defineComponent({
props:['data'],
name: 'ChildComponent',
setup() {
return {
text: ref(''),
dataIn:{}
};
},
mounted(){
this.dataIn = this.data
},
});
It seems to work but not optimal, i lost my data when i refresh my page. Anyone have a soulution ?
CodePudding user response:
Props should be read readonly.
Your dataIn
approach needs a watcher that will update your dataIn
whenever your data
props change
optionsApi:
export default defineComponent({
props:['data'],
name: 'ChildComponent',
data() {
text: '',
data: this.dataIn,
}
watcher: {
dataIn: (newValue,oldValue){
this.data = newValue
}
}
});
CodePudding user response:
It seems that you want to make change to your data on your child component, you have to make it two-way binding. You should change your child code like this ( you are using custom q-input in your component and the attributes may differ a little but it is the same concept) :
<q-input
:value="value"
v-bind="$attrs"
v-on="$listeners"
@input="(v) => $emit('input', v)"
/>
and instead of using data prop you should change it to value :
props: {
value: {
type: [String], // multiple type also defenition accepted
default: "",
},
}
then in your parent simply use child component like this :
<your-child-component v-model="someData" />
CodePudding user response:
If I understood you correctly, you need to emit event from child or to use computed property with getter/setter:
const { ref, onMounted, watch } = Vue
const app = Vue.createApp({
setup() {
const items = ref({})
const getData = () => {
items.value = ({id: 1, message: 'aaa'})
/*axios.get('/api/Hotel/' 2).then((response) => {
this.data = response.data;
this.fixed = true,
console.log(this.data);
});*/
}
onMounted(async() => await getData())
//