vue部分

 DialogComponent.vue 
<template>
  <div class="dialog-pc" v-if="visible">
    <div class="dialog-main">
      <div class="dialog-title">{{ title }}</div>
      <div class="dialog-body">
        <p class="p1" v-if="content">{{ content }}</p>
        <p class="p1" v-if="contentHtml" v-html="contentHtml"></p>
        <p v-if="tip" class="p2">{{ tip }}</p>
      </div>
      <div class="dialog-footer">
        <div class="btn confirm" @click="handleConfirm">确定</div>
        <div class="btn cancel" @click="handleCancel">取消</div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      visible: true,
    }
  },
  props: {
    title: {
      type: String,
      default: function () {
        return '提示'
      },
    },
    content: {
      type: String,
      default: '',
    },
    tip: {
      type: String,
      default: '',
    },
    contentHtml: {
      type: String,
      default: '',
    },
  },
  methods: {
    handleConfirm() {
      this.visible = false
      this.$emit('confirm')
    },
    handleCancel() {
      this.visible = false
      this.$emit('cancel')
    },
  },
}
</script>
<style lang="scss" scoped>
.dialog-pc {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 999;
  .dialog-main {
    width: 500px;
    background-color: #ffffff;
    border-radius: 30px;

    .dialog-title {
      width: 500px;
      height: 60px;
      background-color: #f5f5f5;
      border-radius: 30px 30px 0px 0px;
      box-sizing: border-box;
      padding: 0 30px;
      line-height: 60px;
      font-size: 18px;
      font-weight: bold;
    }

    .dialog-body {
      width: 500px;
      min-height: 120px;
      padding: 30px;
      box-sizing: border-box;

      .p1 {
        font-size: 16px;
        line-height: 24px;
        color: #333333;
      }

      .p2 {
        margin-top: 20px;
        font-size: 14px;
        line-height: 24px;
        color: #999999;
      }
    }

    .dialog-footer {
      height: 90px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding: 0 30px;
      box-sizing: border-box;

      .btn {
        width: 100px;
        height: 36px;
        border-radius: 18px;
        border: solid 1px #cccccc;
        text-align: center;
        line-height: 36px;
        font-size: 16px;
        color: #333333;
        cursor: pointer;

        &.confirm {
          margin-right: 20px;
          border: none;
          background-color: #ffc600;
          color: #723500;
        }
      }
    }
  }
}
</style>

js部分

// dialog.js
import Vue from 'vue';
import DialogComponent from './dialog-pc.vue';
export default function showDialog({ title, content,tip,contentHtml }) {
    return new Promise((resolve, reject) => {
  
        const dialogInstance = new Vue({
            render(h) {
                return h(DialogComponent, {
                    props: {
                        title:title,
                        content:content,
                        tip:tip,
                        contentHtml:contentHtml,
                    },
                    on: {
                        confirm: () => {
                            dialogInstance.$destroy(); document.body.removeChild(dialogInstance.$el);
                            resolve(true);
                        },
                        cancel: () => {
                            dialogInstance.$destroy();
                            document.body.removeChild(dialogInstance.$el);
                            reject(false);
                        }
                    }
                });
            }
        }).$mount(); document.body.appendChild(dialogInstance.$el);
    });
}
main.js

// 全局注册dialog
import DialogPc from '@/components/dialog/dialog-pc.js';
Vue.prototype.$dialogPc = DialogPc;

页面调用

   this.$dialogPc({
        contentHtml: '是否确认删除<span style=color:#ff8b02>1</span>堂课?',
        tip: '删除后无法恢复相关数据',
      }).then(() => {
        console.log('删除')
      }).catch(()=>{
        console.log('取消')
      })

当 showDialog 函数被调用时,它接收一个包含 title 和 content 的对象作为参数。
这个函数返回一个 Promise 对象,该对象在对话框的确认或取消操作后会被解析或拒绝。
在函数内部,首先创建了一个 Vue 实例 dialogInstance,并将其挂载到文档之外。
这个实例使用了 DialogComponent.vue 文件中定义的组件,并传递了 title 和 content 作为组件的属性。
同时,通过监听组件的 confirm 和 cancel 事件,来执行对应的解析和拒绝操作。
当用户点击确认或取消按钮时,DialogComponent.vue 中的对应方法会被触发,然后在 showDialog 函数中执行解析或拒绝 Promise 的操作。
最后,通过销毁 Vue 实例和从文档中移除组件的方式关闭对话框,以确保内存的正确释放和界面的更新。

当showDialog函数被调用时,它会创建一个新的Vue实例,然后使用这个实例的render函数来渲染一个Vue组件。
在这种情况下,这个Vue组件是DialogComponent.vue。
在render函数中,通过h参数,它创建了一个DialogComponent组件实例,并传递了一些配置:props: 通过props属性,将title和content的值传递给DialogComponent组件,这样组件就可以使用这些属性来显示对话框的标题和内容。
on: 通过on属性,监听了DialogComponent组件中的两个事件:confirm和cancel。当用户点击对话框中的确认或取消按钮时,这些事件将被触发。然后,当用户点击确认按钮时,confirm事件会调用resolve(true)来解析Promise,表示用户选择了确认操作。
当用户点击取消按钮时,cancel事件会调用reject(false)来拒绝Promise,表示用户选择了取消操作。
这个render函数的目的是将DialogComponent组件渲染到DOM中,以显示对话框,并确保对话框的交互可以正确地处理确认和取消操作。
这两句代码在关闭对话框时执行。
dialogInstance.$destroy();: 这一行代码调用了 Vue 实例的 d e s t r o y 方法,它会触发 V u e 生命周期钩子函数 b e f o r e D e s t r o y 和 d e s t r o y e d ,并且将当前实例及其子实例从 V u e 的实例列表中移除,释放它们占用的内存。这一步确保了对话框组件及其相关资源被正确销毁。 d o c u m e n t . b o d y . r e m o v e C h i l d ( d i a l o g I n s t a n c e . destroy 方法,它会触发 Vue 生命周期钩子函数 beforeDestroy 和 destroyed,并且将当前实例及其子实例从 Vue 的实例列表中移除,释放它们占用的内存。 这一步确保了对话框组件及其相关资源被正确销毁。 document.body.removeChild(dialogInstance. destroy方法,它会触发Vue生命周期钩子函数beforeDestroydestroyed,并且将当前实例及其子实例从Vue的实例列表中移除,释放它们占用的内存。这一步确保了对话框组件及其相关资源被正确销毁。document.body.removeChild(dialogInstance.el);:
这一行代码从 DOM 中移除了对话框的根元素。
由于 Vue 实例的 $el 属性指向其挂载的 DOM 元素,因此可以通过 document.body.removeChild() 方法将其从文档中移除。
这一步确保了对话框在关闭时被从界面上完全移除。
这两行代码的目的是确保在关闭对话框后,释放对话框组件及其相关资源,并从界面上移除对话框元素,以便于下次再次打开时重新创建。

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐