【发布时间】:2020-04-11 17:45:49
【问题描述】:
我需要在不同的组件中使用 Vuetify v-date-picker。但这会导致代码重复。所以我认为创建一个自定义的<custom-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: "value"
found in
---> <CustomDatePicker> at components/CustomDatePicker.vue
<Pages/index.vue> at pages/index.vue
父组件是 pages/index.vue:
<template>
<div>
<custom-date-picker v-model="date" />
<v-btn @click="getDate">
Ok
</v-btn>
</div>
</template>
<script>
import CustomDatePicker from '@/components/CustomDatePicker.vue'
export default {
components: { CustomDatePicker },
data () {
return {
date: ''
}
},
methods: {
getDate () {
console.log(this.date)
}
}
}
</script>
子组件是 components/CustomDatePicker.vue:
<template>
<v-container fill-height>
<v-row justify="center" align="center">
<v-col cols="12">
<!-- Date picker -->
<v-menu
ref="menu1"
v-model="menu1"
:close-on-content-click="false"
transition="scale-transition"
offset-y
>
<template v-slot:activator="{ on }">
<v-text-field
v-bind:value="value"
v-on:input="$emit('input', $event)"
@blur="date = parseDate(value)"
v-on="on"
value
label="Date"
color="green lighten-1"
/>
</template>
<v-date-picker
v-model="date"
@input="menu1 = false"
no-title
header-color="green lighten-1"
color="green lighten-1"
/>
</v-menu>
<!-- end of date picker -->
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
name: 'CustomDatePicker',
props: {
value: {
type: String,
default: ''
}
},
data () {
return {
menu1: null,
date: null
}
},
computed: {
computedDateFormatted () {
return this.formatDate(this.date)
}
},
watch: {
date (val) {
this.value = this.formatDate(this.date)
}
},
methods: {
formatDate (date) {
if (!date) { return null }
return date
},
parseDate (date) {
if (!date) { return null }
const [year, month, day] = date.split('-')
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
}
}
}
</script>
如何解决我的问题?
如果你有时间的话,这个simple demo 可以在 Github 上找到:)
更新 1:
我通过避免改变 prop value 成功摆脱了上面的错误消息。我可以选择日期,当我点击 Ok 按钮时,我会正确记录日期控制台。
问题是父组件的文本字段没有显示我选择的日期,它保持如上图所示。
下面是子组件的更新代码:
<template>
<v-container fill-height>
<v-row justify="center" align="center">
<v-col cols="12">
<!-- Date picker -->
<v-menu
ref="menu1"
v-model="menu1"
:close-on-content-click="false"
transition="scale-transition"
offset-y
>
<template v-slot:activator="{ on }">
<v-text-field
v-model="dateFormatted"
@blur="date = parseDate(dateFormatted)"
v-on="on"
value
label="Date"
color="green lighten-1"
/>
</template>
<v-date-picker
v-bind:value="value"
v-on:input="$emit('input', $event)"
@input="menu1 = false"
no-title
header-color="green lighten-1"
color="green lighten-1"
/>
</v-menu>
<!-- end of date picker -->
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
name: 'CustomDatePicker',
props: {
value: {
type: String,
default: ''
}
},
data () {
return {
menu1: null,
date: null,
dateFormatted: null
}
},
computed: {
computedDateFormatted () {
return this.formatDate(this.date)
}
},
watch: {
date (val) {
this.dateFormatted = this.formatDate(this.date)
}
},
methods: {
formatDate (date) {
if (!date) { return null }
return date
},
parseDate (date) {
if (!date) { return null }
const [year, month, day] = date.split('-')
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
}
}
}
</script>
【问题讨论】:
-
如何克服我的问题 ...我建议你避免直接改变道具和相反,使用数据或基于道具值的计算属性
-
谢谢,这正是我现在避免的(在我发布问题之后),当我按下按钮时,我得到了选择的日期,但它暂时没有反映在文本字段中(它保持在图片上)@JaromandaX
-
你发布了新代码@JaromandaX 吗?
-
我用相关代码和解释更新了我的帖子。 @Djip
-
我用一半工作代码@JaromandaX 更新了我的问题
标签: javascript vue.js vuetify.js nuxt.js