Vue.js 对话框/模态在父组件上关闭
Posted
技术标签:
【中文标题】Vue.js 对话框/模态在父组件上关闭【英文标题】:Vue.js dialog/modal closes on parent component 【发布时间】:2019-09-14 04:54:37 【问题描述】:我试图在另一个组件中打开我的 CanvasPreview 组件,但它失败了, 首先,它会快速显示对话框/模式,然后如果我打开 Vue Dev 工具,它会再次隐藏 如果我在控制台中手动将 showCanvasPreview 编辑为 true,则显示模式将被设置为 false。 所以我猜它又被设置为 false,但我不明白为什么。
这是对话框/模态组件:
<template>
<v-dialog
v-model="show"
>
<v-card>
<v-card-actions>
<v-container grid-list-md text-xs-center>
<v-layout row wrap>
</v-layout>
</v-container>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import CanvasPreviewSourceUpload from './CanvasPreviewSourceUpload';
export default
components:
'canvas-preview-source-upload': CanvasPreviewSourceUpload
,
props:
imgSrc: String,
visible: Boolean
,
computed:
show:
get ()
return this.visible;
,
set (visible)
if (!visible)
this.$emit('closePreview');
,
</script>
在我的父组件中,我这样调用预览组件:
<template>
<div>
//... some more html
<div id="canvas-body">
<canvas id="pdf-render"></canvas>
<canvas id="selectCanvas"
@mousedown="markElementOnMouseDown"
@mousemove="updatePreview"
@mouseup="markElementOnMouseUp">
</canvas>
</div>
<canvas-preview
:imgSrc="this.targetImage.src"
:visible="showCanvasPreview"
@closePreview="showCanvasPreview=false">
</canvas-preview>
</div>
</template>
<script>
import CanvasPreview from '@/js/components/CanvasPreview';
export default
components:
'canvas-preview': CanvasPreview
,
props:
'name': String
,
data: () => (
showCanvasPreview: false,
...
),
methods:
markElementOnMouseUp (event)
this.isDragging = false;
this.targetImage.src = this.clipCanvas.toDataURL();
this.targetImage.style.display = 'block';
this.showCanvasPreview = true;
console.log("mouseup: " + this.showCanvasPreview);
,
</script>
【问题讨论】:
您介意提供 CodePen 吗? @MattOestreich 我可以试试,如果你有兴趣,我也可以通过 ngrok 链接分享项目的当前状态 【参考方案1】:试试这个
<v-dialog
v-model="show"
>
<v-card>
<v-card-actions>
<v-container grid-list-md text-xs-center>
<v-layout row wrap>
<canvas-preview-source-upload
:imgSrc="imgSrc"
@close.stop="show=false">
</canvas-preview-source-upload>
</v-layout>
</v-container>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import CanvasPreviewSourceUpload from './CanvasPreviewSourceUpload';
export default
components:
'canvas-preview-source-upload': CanvasPreviewSourceUpload
,
data: ()=> (
show: false
),
props:
imgSrc: String,
visible: Boolean
,
watch:
show(isShow)
if (!isShow)
this.$emit('closePreview');
visible(isVisible)
this.show = isVisible;
</script>```
【讨论】:
感谢您的回答,但同样的错误是否会出现其他想法? 如果你能提供进一步的支持我真的很坚持这一点【参考方案2】:这样的事情应该允许您从单独的组件打开v-dialog
..
如果您提供包含您的代码的 CodePen 或 CodeSandbox,我们将能够更好地为您提供帮助。
[CodePen mirror]
const dialog =
template: "#dialog",
props:
value:
type: Boolean,
required: true
,
,
computed:
show:
get()
return this.value;
,
set(value)
this.$emit("input", value);
,
;
const dialogWrapper =
template: "#dialogWrapper",
components:
appDialog: dialog,
,
data()
return
isShown: false,
new Vue(
el: "#app",
components:
dialogWrapper
);
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@1.5.6/dist/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/vuetify@1.5.6/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app>
<v-content>
<dialog-wrapper/>
</v-content>
</v-app>
</div>
<script type="text/x-template" id="dialog">
<v-dialog v-model="show">
<v-card>
<v-card-actions pa-0>
<v-spacer/>
<v-btn dark small color="red" @click="show = false">Close</v-btn>
<v-spacer/>
</v-card-actions>
<v-card-title class="justify-center">
<h2>
Hello from the child dialog
</h2>
</v-card-title>
</v-card>
</v-dialog>
</script>
<script type="text/x-template" id="dialogWrapper">
<div>
<h1 class="text-xs-center">I am the wrapper/parent</h1>
<v-container>
<v-layout justify-center>
<v-btn color="primary" dark @click.stop="isShown = true">
Open Dialog
</v-btn>
</v-layout>
</v-container>
<app-dialog v-model="isShown"></app-dialog>
</div>
</script>
【讨论】:
以上是关于Vue.js 对话框/模态在父组件上关闭的主要内容,如果未能解决你的问题,请参考以下文章