Bil*_*adj 1 javascript vue.js nuxt.js vuetify.js
我需要v-date-picker在不同的组件中使用 Vuetify 。但这会导致代码重复。所以我认为创建一个<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
Run Code Online (Sandbox Code Playgroud)
父组件是 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>
Run Code Online (Sandbox Code Playgroud)
子组件是 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>
Run Code Online (Sandbox Code Playgroud)
如何克服我的问题?
如果您有时间,可以在 Github 上找到这个简单的演示:)
更新1:
我通过避免改变 prop 成功地摆脱了上面的错误消息value。我可以选择日期,当我单击“确定”按钮时,我会正确记录日期控制台。
问题是父组件的文本字段没有显示我选择的日期,它保持如上图所示。
这是子组件的更新代码:
<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>
Run Code Online (Sandbox Code Playgroud)
我为使其正常工作所做的更改是,我添加了computed一个get()和set()。getter 将返回当前选定的值,setter 将在每次更改时发出新值。
这是利用v-model内部自定义组件的好方法。
自定义日期选择器.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-model="selected"
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="selected"
@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: {
selected: {
get() {
return this.value
},
set(value) {
this.$emit('input', value)
}
},
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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4174 次 |
| 最近记录: |