我在当前项目中使用Vue的Vuetify框架,并且已经基于v-date-picker创建了一个自定义组件,并计划在多个地方使用。下面是代码;
子组件(自定义v-date-picker)
<template>
<v-dialog
ref="dialog"
v-model="modal"
:return-value.sync="date"
persistent
width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
v-model="date"
:label=title
prepend-icon="event"
readonly
v-on="on"
></v-text-field>
</template>
<v-date-picker v-model="date" scrollable>
<v-spacer></v-spacer>
<v-btn text color="primary" @click="modal = false">Cancel</v-btn>
<v-btn text color="primary" @click="$refs.dialog.save(date)">OK</v-btn>
</v-date-picker>
</v-dialog>
</template>
<script>
export default {
props:[
'title','date'
],
data () {
return {
modal:false,
}
},
}
</script>
父组件(这是一个对话框)
<template>
<v-dialog
width="800px"
v-model="dialog"
>
<v-card>
<!-- <v-card-title class="grey darken-2">
Create contact
</v-card-title> -->
<v-container>
<v-row class="mx-2">
<v-col cols="3">
<date-picker-component :date="beginDate" title="Begin Date"></date-picker-component>
</v-col>
<v-col cols="3">
<date-picker-component :date="endDate" title="End Date"></date-picker-component>
</v-col>
</v-row>
</v-container>
<v-card-actions>
<v-spacer />
<v-btn
text
color="primary"
@click="dialog = false"
>Cancel</v-btn>
<v-btn
text
@click="createEvent"
>Create Event</v-btn>
</v-card-actions>
</v-card>
<v-overlay :value="overlay">
<v-progress-circular indeterminate size="64"></v-progress-circular>
</v-overlay>
<v-dialog
v-model="resultDialog"
max-width="290"
>
<v-card>
<v-card-title class="headline"><v-icon class="pr-2" color="green" st>mdi-check-circle</v-icon> Event Manager</v-card-title>
<v-card-text>
{{resultDialogMessage}}
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="green darken-1"
text
@click="resultDialog = false"
>
OK
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-dialog>
</template>
<script>
import Vue from 'vue';
import DatePicker from "../../widgets/DatePicker";
export default {
name: 'CreateEvent',
props:['dialog'],
components:{
'date-picker-component':DatePicker,
},
data () {
return {
resultDialog:false,
resultDialogMessage:"",
overlay:false,
beginDate:new Date().toISOString().substr(0, 10),
endDate:new Date().toISOString().substr(0, 10),
}
},
};
</script>
v-date-picker可以正常工作,但是我立即选择一个日期,在控制台中出现以下错误;
[Vue warn]: 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: "date
结果,我无法从子组件中获取所选日期,并且该日期仅恢复为初始日期。
是否有我遗漏的东西,我在做什么错?
答案 0 :(得分:2)
在给子级的vue数据中,组件应作为prop传递给父组件,并应通过回传来传递给父组件。如果您使用相同的变量传递和释放值,则vue会警告您。您需要按以下方式更改日期选择器组件,以使道具不会直接被孩子更改。而是使用本地数据。
<template>
<v-dialog
ref="dialog"
v-model="modal"
:return-value.sync="localDate" //Changed here
persistent
width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
v-model="localDate" //Changed here
:label=title
prepend-icon="event"
readonly
v-on="on"
></v-text-field>
</template>
<v-date-picker v-model="localDate" scrollable> //Changed here
<v-spacer></v-spacer>
<v-btn text color="primary" @click="modal = false">Cancel</v-btn>
<v-btn text color="primary" @click="$refs.dialog.save(localDate)">OK</v-btn> //Changed here
</v-date-picker>
</v-dialog>
</template>
<script>
export default {
props:[
'title','date'
],
data () {
return {
modal:false,,
localDate: this.date
}
},
watch: {
localDate(){
this.$emit('update', this.localDate)
}
}
}
</script>
现在在您的父组件中,您将按以下方式使用
<date-picker-component
:date="endDate"
@update="(v) => (endDate = v)"
title="End Date">
</date-picker-component>