
流程:

组件:
<template> <div class="xtx-confirm" :class="{fade}"> <div class="wrapper" :class="{fade}"> <div class="header"> <h3>{{title}}</h3> <a @click="cancelCallback()" href="JavaScript:;" class="iconfont icon-close-new"></a> </div> <div class="body"> <i class="iconfont icon-warning"></i> <span>{{text}}</span> </div> <div class="footer"> <XtxButton @click="cancelCallback()" size="mini" type="gray">取消</XtxButton> <XtxButton @click="submitCallback()" size="mini" type="primary">确认</XtxButton> </div> </div> </div></template><script>// 当前组件不是在APP下进行渲染,无法使用APP下的环境(全局组件,全局指令,原型属性函数)import XtxButton from '@/components/XtxButton.vue'import { onMounted, ref } from 'vue'export default { name: 'XtxConfirm', components: { XtxButton }, props: { title: { type: String, default: '温馨提示' }, text: { type: String, default: '' }, submitCallback: { type: Function }, cancelCallback: { type: Function } }, setup () { const fade = ref(false) onMounted(() => { // 当元素渲染完毕立即过渡的动画不会触发 fade.value = true }) return { fade } }}</script><style scoped lang="less">.xtx-confirm { position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 8888; background: rgba(0,0,0,0); &.fade { transition: all 0.4s; background: rgba(0,0,0,.5); } .wrapper { width: 400px; background: #fff; border-radius: 4px; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-60%); opacity: 0; &.fade { transition: all 0.4s; transform: translate(-50%,-50%); opacity: 1; } .header,.footer { height: 50px; line-height: 50px; padding: 0 20px; } .body { padding: 20px 40px; font-size: 16px; .icon-warning { color: @priceColor; margin-right: 3px; font-size: 16px; } } .footer { text-align: right; .xtx-button { margin-left: 20px; } } .header { position: relative; h3 { font-weight: normal; font-size: 18px; } a { position: absolute; right: 15px; top: 15px; font-size: 20px; width: 20px; height: 20px; line-height: 20px; text-align: center; color: #999; &:hover { color: #666; } } } }}</style>
转换成函数调用
Confirm.js
// 实现使用函数调用xtx-message组件的逻辑// 引入 创建虚拟节点 和渲染方法import { createVNode, render } from 'vue'// 引入信息提示组件import XtxConfirm from './xtxConfirm'// 准备dom容器const div = document.createElement('div')// 添加类名div.setAttribute('class', 'xtx-message-container')// 添加到body上document.body.appendChild(div)// 该函数渲染XtxConfirm组件,标题和文本// 函数的返回值是promise对象export default ({ type, text }) => { return new Promise((resolve, reject) => { // 1. 渲染组件 // 2. 点击确认按钮,触发resolve同时销毁组件 // 3. 点击取消按钮,触发reject同时销毁组件 const submitCallback = () => { render(null, div) resolve() } const cancelCallback = () => { render(null, div) // 希望给出promise错误原因 reject(new Error()) } // 实现:根据xtx-message.vue渲染消息提示 // 1. 导入组件 // 2. 根据组件创建虚拟节点 第一个参数为要创建的虚拟节点 第二个参数为props的参数 const vnode = createVNode(XtxConfirm, { type, text, submitCallback, cancelCallback }) // 3. 准备一个DOM容器 // 4. 把虚拟节点渲染DOM容器中 render(vnode, div) })}
使用:
<button @click="delete">删除</button><script>import Confirm from '@/components/confirm'export default { setup () { const delete= () => { Confirm({ text: '您确定从购物车删除该商品吗?' }).then(() => { console.log('点击确认') }).catch(e => { console.log('点击取消') }) } return { delete} }}</script>