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 对话框/模态在父组件上关闭的主要内容,如果未能解决你的问题,请参考以下文章

Bootstrap模态对话框怎么隐藏?

Vue模态框的封装

如何在 vue 上使用 eventBus 触发点击事件?

Vue.js模态组件示例未关闭

如何在WPF中进行模态对话?

如何*保存*角度材料模态对话框的结果?