【发布时间】:2019-12-05 12:44:07
【问题描述】:
在 Vue/Vuetify 中,我们如何从父级隐藏/显示对话框?我正在尝试使用v-model,这是我的设置的简化版本:
父组件(只是一个触发子组件显示的按钮)
<template>
<div>
<v-btn class="ma-2" outlined fab color="red" small @click.stop="editItem()">
<v-icon size="16">mdi-close-circle</v-icon>
</v-btn>
<user-dialog v-model="dialog" :eitem="editedItem" class="elevation-2" />
</div>
</template>
<script>
import UserDialog from "./UserDialog.vue";
export default {
components:{
UserDialog
},
data() {
return {
counter: 0,
dialog: false,
editedItem: {},
}
},
methods: {
editItem: function() {
this.counter++;
this.editedItem = Object.assign({}, {
title: 'some title' + this.counter,
details: 'some details for this item'
});
this.dialog = true;
},
},
}
</script>
子组件(基本上是一个对话框)
<template>
<v-dialog v-model="value" max-width="500px">
<v-card>
<v-card-title>
<span class="headline">A Dialog</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12>
<v-text-field v-model="eitem.title" label="Title"></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field v-model="eitem.details" label="Details"></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click.stop="save">Save</v-btn>
<v-btn color="blue darken-1" text @click.stop="close">Cancel</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
value: Boolean,
eitem: Object,
},
data() {
return {
editedItem: this.eitem,
}
},
methods: {
save() {
//perform save
this.$emit('input', false);
},
close() {
this.$emit('input', false);
},
},
}
</script>
此设置有效,但会发出以下警告:
避免直接改变 prop,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于道具值的数据或计算属性。正在变异的道具:“价值”
但是如果按照这个建议行事并在子组件中声明一个data 项并将v-dialog 的v-model 设置为此数据项,则对话框在单击时停止显示。
我也许理解它为什么会这样,但无法找出一个不显示警告的正确方法来解决这个问题。谁能帮我解决这个问题?
【问题讨论】:
-
而不是使用
v-model将v-text-field的值绑定到道具。在input上向父级发出一个自定义事件并让它更新道具的值。您可以将计算属性与 getter/setter 一起使用。 -
@HusamIbrahim:我听说
v-model是一种语法糖,它与您描述的完全一样。这种方法有何不同? -
澄清一下,这些文本字段绑定现在不是问题。目前,我实际上正在为
v-dialog的v-model苦苦挣扎。我理解的问题的要点是我需要一种方法将本地data项与prop绑定,以便每当父组件更改其绑定的数据项时,子组件都会收到有关此更改的通知并在响应子组件更新其本地数据项(然后将触发 v-dialog 出现或消失.. -
不同之处在于
v-model将尝试直接修改输入值,这相当于@input="value=$event.target.value"。您想要的是通过@input="()=>{$emit('updateValue', newValue}"向父级发出自定义事件,并让父级监听updateValue事件以更新道具的值。这将在更新后自动反映在子组件中。 -
我看到您声明
value作为与v-dialog一起使用的道具,但您没有从父级传递它的值。在这种情况下,您应该指定一个默认值。而不是在值上使用v-model,而是直接使用带有getter/setter的计算属性。这样,如果从父级传递值,您可以向父级发出自定义事件以更新道具的值。否则,您可以改为更新本地值。
标签: javascript vue.js vuetify.js