Javascript 创建对话框组件并显示/隐藏父组件

Javascript 创建对话框组件并显示/隐藏父组件,javascript,vue.js,vuetify.js,Javascript,Vue.js,Vuetify.js,在Vue/Vuetify中,如何对父级隐藏/显示对话框?我正在尝试使用v-model,以下是我的设置的简化版本: 父组件(只是一个触发子组件显示的按钮) 闭合圆 从“/UserDialog.vue”导入UserDialog; 导出默认值{ 组成部分:{ 用户对话框 }, 数据(){ 返回{ 柜台:0,, 对话:错, 编辑项:{}, } }, 方法:{ editItem:函数(){ 这个.counter++; this.editem=Object.assign({}{ 标题:'某个标题'+此计数

在Vue/Vuetify中,如何对父级隐藏/显示对话框?我正在尝试使用
v-model
,以下是我的设置的简化版本:

父组件(只是一个触发子组件显示的按钮)


闭合圆
从“/UserDialog.vue”导入UserDialog;
导出默认值{
组成部分:{
用户对话框
},
数据(){
返回{
柜台:0,,
对话:错,
编辑项:{},
}
},
方法:{
editItem:函数(){
这个.counter++;
this.editem=Object.assign({}{
标题:'某个标题'+此计数器,
详细信息:“此项目的一些详细信息”
});        
this.dialog=true;
},
},
}
子组件(基本上是一个对话框)


对话
拯救
取消
导出默认值{
道具:{
值:布尔,
eitem:对象,
},
数据(){
返回{
伊迪特姆:这个,
}
},
方法:{
保存(){
//执行保存
这是。$emit('input',false);
},
关闭(){
这是。$emit('input',false);
},
},
}
此设置有效,但会发出以下警告:

避免直接改变道具,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于道具值的数据或计算属性。道具变异:“价值”

但是,如果根据此建议执行操作,并在子组件中声明
数据
项,并将
v-dialog
v-model
设置为此数据项,则单击后对话框将停止显示


我可能理解它为什么会这样做,但无法找到一种不显示警告的正确修复方法。有人能帮我吗?

因为Vue在你变异
道具时会发出警告,所以你不应该将
v-model
道具一起使用。要处理此问题,请使用以下模式:

computed: {
  propModel: {
    get () { return this.value },
    set (value) { this.$emit('input', value) },
  },
},
使用getter定义
computed
属性,getter返回
props.value
,setter发出
input
事件(由于使用
v-model
,因此将在父级中成功处理)

不要忘记更改您的
模板

而不是使用
v-model
v-text-field
的值绑定到道具。在
input
上,向父级发出一个自定义事件,并让它更新道具的值。您可以将计算属性与getter/setter一起使用。@HusamIbrahim:我听说
v-model
是一种语法糖,它完全符合您描述的内容。这种方法有什么不同?只是澄清一下,这些文本字段绑定现在不是问题所在。实际上,我现在正在努力解决
v-dialog
v-model
。我理解的问题的要点是,我需要一种方法将本地
数据
项与
属性
绑定,这样每当父组件更改其绑定的数据项时,子组件都会收到有关此更改的通知,作为响应,子组件更新其本地数据项(这将触发v-dialog出现或消失。)区别在于,
v-model
将尝试直接修改输入上的值,这相当于
@input=“value=$event.target.value”
。您想要的是通过
@input=“()=>{$emit('updateValue',newValue}向父级发送自定义事件
并让父级侦听
updateValue
事件以更新道具的值。更新后,该事件将自动反映在子组件中。我看到您将
value
声明为要与
v-dialog
一起使用的道具,但您不会从父级传递它的值。在这种情况下,您应该指定默认值。在值上不使用
v-model
,而是直接使用带有getter/setter的计算属性。这样,如果从父级传递值,则可以向父级发送自定义事件以更新prop的值。否则,可以改为更新本地值。
<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>
computed: {
  propModel: {
    get () { return this.value },
    set (value) { this.$emit('input', value) },
  },
},