image.png

流程:

image.png

组件:

  1. <template>
  2. <div class="xtx-confirm" :class="{fade}">
  3. <div class="wrapper" :class="{fade}">
  4. <div class="header">
  5. <h3>{{title}}</h3>
  6. <a @click="cancelCallback()" href="JavaScript:;" class="iconfont icon-close-new"></a>
  7. </div>
  8. <div class="body">
  9. <i class="iconfont icon-warning"></i>
  10. <span>{{text}}</span>
  11. </div>
  12. <div class="footer">
  13. <XtxButton @click="cancelCallback()" size="mini" type="gray">取消</XtxButton>
  14. <XtxButton @click="submitCallback()" size="mini" type="primary">确认</XtxButton>
  15. </div>
  16. </div>
  17. </div>
  18. </template>
  19. <script>
  20. // 当前组件不是在APP下进行渲染,无法使用APP下的环境(全局组件,全局指令,原型属性函数)
  21. import XtxButton from '@/components/XtxButton.vue'
  22. import { onMounted, ref } from 'vue'
  23. export default {
  24. name: 'XtxConfirm',
  25. components: { XtxButton },
  26. props: {
  27. title: {
  28. type: String,
  29. default: '温馨提示'
  30. },
  31. text: {
  32. type: String,
  33. default: ''
  34. },
  35. submitCallback: {
  36. type: Function
  37. },
  38. cancelCallback: {
  39. type: Function
  40. }
  41. },
  42. setup () {
  43. const fade = ref(false)
  44. onMounted(() => {
  45. // 当元素渲染完毕立即过渡的动画不会触发
  46. fade.value = true
  47. })
  48. return { fade }
  49. }
  50. }
  51. </script>
  52. <style scoped lang="less">
  53. .xtx-confirm {
  54. position: fixed;
  55. left: 0;
  56. top: 0;
  57. width: 100%;
  58. height: 100%;
  59. z-index: 8888;
  60. background: rgba(0,0,0,0);
  61. &.fade {
  62. transition: all 0.4s;
  63. background: rgba(0,0,0,.5);
  64. }
  65. .wrapper {
  66. width: 400px;
  67. background: #fff;
  68. border-radius: 4px;
  69. position: absolute;
  70. top: 50%;
  71. left: 50%;
  72. transform: translate(-50%,-60%);
  73. opacity: 0;
  74. &.fade {
  75. transition: all 0.4s;
  76. transform: translate(-50%,-50%);
  77. opacity: 1;
  78. }
  79. .header,.footer {
  80. height: 50px;
  81. line-height: 50px;
  82. padding: 0 20px;
  83. }
  84. .body {
  85. padding: 20px 40px;
  86. font-size: 16px;
  87. .icon-warning {
  88. color: @priceColor;
  89. margin-right: 3px;
  90. font-size: 16px;
  91. }
  92. }
  93. .footer {
  94. text-align: right;
  95. .xtx-button {
  96. margin-left: 20px;
  97. }
  98. }
  99. .header {
  100. position: relative;
  101. h3 {
  102. font-weight: normal;
  103. font-size: 18px;
  104. }
  105. a {
  106. position: absolute;
  107. right: 15px;
  108. top: 15px;
  109. font-size: 20px;
  110. width: 20px;
  111. height: 20px;
  112. line-height: 20px;
  113. text-align: center;
  114. color: #999;
  115. &:hover {
  116. color: #666;
  117. }
  118. }
  119. }
  120. }
  121. }
  122. </style>

转换成函数调用

Confirm.js

  1. // 实现使用函数调用xtx-message组件的逻辑
  2. // 引入 创建虚拟节点 和渲染方法
  3. import { createVNode, render } from 'vue'
  4. // 引入信息提示组件
  5. import XtxConfirm from './xtxConfirm'
  6. // 准备dom容器
  7. const div = document.createElement('div')
  8. // 添加类名
  9. div.setAttribute('class', 'xtx-message-container')
  10. // 添加到body上
  11. document.body.appendChild(div)
  12. // 该函数渲染XtxConfirm组件,标题和文本
  13. // 函数的返回值是promise对象
  14. export default ({ type, text }) => {
  15. return new Promise((resolve, reject) => {
  16. // 1. 渲染组件
  17. // 2. 点击确认按钮,触发resolve同时销毁组件
  18. // 3. 点击取消按钮,触发reject同时销毁组件
  19. const submitCallback = () => {
  20. render(null, div)
  21. resolve()
  22. }
  23. const cancelCallback = () => {
  24. render(null, div)
  25. // 希望给出promise错误原因
  26. reject(new Error())
  27. }
  28. // 实现:根据xtx-message.vue渲染消息提示
  29. // 1. 导入组件
  30. // 2. 根据组件创建虚拟节点 第一个参数为要创建的虚拟节点 第二个参数为props的参数
  31. const vnode = createVNode(XtxConfirm, { type, text, submitCallback, cancelCallback })
  32. // 3. 准备一个DOM容器
  33. // 4. 把虚拟节点渲染DOM容器中
  34. render(vnode, div)
  35. })
  36. }

使用:

  1. <button @click="delete">删除</button>
  2. <script>
  3. import Confirm from '@/components/confirm'
  4. export default {
  5. setup () {
  6. const delete= () => {
  7. Confirm({ text: '您确定从购物车删除该商品吗?' }).then(() => {
  8. console.log('点击确认')
  9. }).catch(e => {
  10. console.log('点击取消')
  11. })
  12. }
  13. return { delete}
  14. }
  15. }
  16. </script>