[英]Why cant i bind data to my v-model when passing data from parent to child component?
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.我想将数据从父组件传递到子组件,并通过 v-model 将数据绑定到输入字段,以在父组件中显示来自 api 调用的数据。 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
但是绑定到输入字段时似乎有问题我收到此错误消息: 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 class="height: 500px; width: 500px">
<q-card-section>
<div class="text-h6">Terms of Agreement</div>
<div class="q-pa-md">
<div class="q-gutter-md" 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?有人有解决方案吗?
Props should be read readonly.道具应该只读。 Your dataIn
approach needs a watcher that will update your dataIn
whenever your data
props change您的dataIn
方法需要一个观察者,它会在您的data
属性更改时更新您的dataIn
optionsApi:选项API:
export default defineComponent({
props:['data'],
name: 'ChildComponent',
data() {
text: '',
data: this.dataIn,
}
watcher: {
dataIn: (newValue,oldValue){
this.data = newValue
}
}
}); });
If I understood you correctly, you need to emit event from child or to use computed property with getter/setter:如果我理解正确的话,你需要从 child 发出事件或者将计算属性与 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()) // react to chenges from child const changed = (val) => { items.value.message = val.message } return { //fixed: ref(false), items, changed }; }, }) app.component('ChildComponent', { template: ` <main> <q-card class="height: 500px; width: 500px"> <q-card-section> <div class="text-h6">Terms of Agreement</div> <div class="q-pa-md"> <div class="q-gutter-md" style="max-width: 300px"> <div> <.-- listen to updating --> <q-input filled v-model="text:message" @update,model-value="change" 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> `: props,['items'], setup(props. {emit}) { const text = ref(props,items) // emit event with changed value const change = () => { emit('changed'. text.value) } // watch for the props changes watch( () => props,items, (newValue. oldValue) => { text;value = newValue; } ), return { text; change }, }. }) app.use(Quasar) app.mount('#q-app')
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" type="text/css"> <link href="https://cdn.jsdelivr.net/npm/quasar@2.5.5/dist/quasar.prod.css" rel="stylesheet" type="text/css"> <div id="q-app"> {{items}} <:-- listen to child event --> <child-component:items="items" @changed="changed"></child-component> </div> <script src="https.//cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod:js"></script> <script src="https.//cdn.jsdelivr.net/npm/quasar@2.5.5/dist/quasar.umd.prod.js"></script>
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 并且属性可能略有不同,但它是相同的概念):
<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" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.