Vue3 — encapsulating cartridges itself — supports the Promise API

background

The most common thing in the list of pages is to add, delete, change and check. The deletion needs to be carefully operated, because once the data is deleted, it is permanent and irreversible. Therefore, when performing such operations, the popbox will be used for secondary confirmation to really confirm that the deletion is being performed to enhance the user experience

Below, we will wrap the shell layer component by ourselves and call $confirm function through vue instance to pop up the confirmation box.

Import function use also needs support.


Component landing code

Basic layout and related data populating

<template>
  <div class="my-confirm" :class="{ fade: fade }">
    <div class="wrapper">
      <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">
        <MyButton @click="cancelCallback()" size="mini" type="gray">cancel</MyButton>
        <MyButton @click="submitCallback()" size="mini" type="primary">confirm</MyButton>
      </div>
    </div>
  </div>
</template>
<script>
// The current component is not rendered under the APP, so the environment under the APP cannot be used (global component, global directive, prototype property function)
import MyButton from '@/components/library/my-button'
import { onMounted, ref } from 'vue'
export default {
  name: 'MyConfirm'.components: { MyButton },
  props: {
    title: {
      type: String.default: 'Warm reminder'
    },
    text: {
      type: String.default: ' '
    },
    submitCallback: {
      type: Function
    },
    cancelCallback: {
      type: Function}},setup() {
    const fade = ref(false)
    onMounted(() = > {
      // Animations that transition immediately after an element is rendered will not be triggered
      setTimeout(() = > {
        fade.value = true
      }, 0)})return { fade }
  }
}
</script>
<style scoped lang="less">
.my-confirm {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 8888;
  background: rgba(0.0.0.0);
  &.fade {
    transition: all 0.4 s;
    background: rgba(0.0.0.0.5);
  }
  .wrapper {
    width: 400px;
    background: #fff;
    border-radius: 4px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -60%);
    opacity: 1;
    &.fade {
      transition: all 0.4 s;
      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>
Copy the code

Create Confirm. Js

Define a confirm. js file under the folder where the global components are located

import { createVNode, render } from 'vue'
import MyConfirm from './my-confirm.vue'

const div = document.createElement('div')
div.setAttribute('class'.'my-confirm')
document.body.appendChild(div)

export default ({ title, text }) => {
  return new Promise((resolve, reject) = > {
    // Click ok
    const submitCallback = () = > {
      render(null, div)
      resolve()
    }
    // Click the cancel button
    const cancelCallback = () = > {
      render(null, div)
      reject(new Error('Click Cancel'))}// 1. Render component
    // 2. Click ok to trigger resolve and destroy the component
    // 3. Click the Cancel button to trigger reject and destroy the component
    const vnode = createVNode(MyConfirm, { title, text, submitCallback, cancelCallback })
    render(vnode, div)
  })
}
Copy the code

use

  1. Use the Confirm method directly

    / / import
    import Confirm from '@/components/library/Confirm'
    
    export default {
        setup() {
            const deleteCart = skuId= > {
               Confirm({ title: 'tip'.text: 'Are you sure you want to delete this item? ' })
                  .then(() = > {
                    Message({ type: 'success'.text: 'Deleted successfully' })
                  })
                  .catch(() = > {
                    // Click the cancel button to trigger
                    Message({ type: 'warn'.text: 'Cancel delete'}}})})Copy the code

    Click ok to trigger then, click cancel to trigger catch

  2. Using the $confirm

    The install function in the index.js file of the global registry component

    app.config.globalProperties.$confirm = Confirm
    Copy the code

    The getCurrentInstance method is introduced when used

    import { getCurrentInstance } from 'vue'
    
    setup(){
        const instance = getCurrentInstance()
        // instance.proxy is equivalent to this in vue2
        instance.proxy.$confirm({ title: 'tip'.text: 'Are you sure you want to delete this item? ' })
                  .then(() = > {
                    Message({ type: 'success'.text: 'Deleted successfully' })
                  })
                  .catch(() = > {
                    // Click the cancel button to trigger
                    Message({ type: 'warn'.text: 'Cancel delete'})})}Copy the code

The effect