美文网首页
vue-删除弹框组件封装

vue-删除弹框组件封装

作者: 温柔vs先生 | 来源:发表于2024-10-13 22:08 被阅读0次

组件

<template>
  <div class="message-box-delete">
    <el-dialog v-model="dialogVisible" width="450" @close="dialogVisible = false">
      <template #header>
        <div class="my-header">
          <div class="left">
            <el-icon v-if="type == 'danger'" :size="24" style="height: 100%">
              <SvgIcon :iconClass="'error'" />
            </el-icon>
            <img v-else src="@/assets/images/command/waring.png" alt="" />

            <span class="text-medium" style="font-size: 20px; font-weight: 600">{{ tip }}</span>
          </div>
        </div>
      </template>

      <slot>
        <span v-if="content && content?.length > 0" class="content text-regular">{{ content }}</span>
        <div v-else>
          <span class="content text-regular"
            >您确认要删除<span class="text-semibold">{{ title }}</span
            >吗?</span
          >
        </div>
      </slot>

      <template #footer>
        <el-button :disabled="isCancelDisabled" @click="onCancel">{{ cancelText }}</el-button>
        <el-button :disabled="isConfirmDisabled" type="primary" @click="onConfirm"> {{ confirmText }} </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ElButton, ElDialog, ElIcon } from 'element-plus';
import SvgIcon from '@/components/SvgIcon/index';

const emit = defineEmits(['update:visible', 'confirm', 'cancel']);

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  tip: {
    type: String,
    default: '删除',
  },
  title: {
    type: String,
    default: '',
  },
  content: {
    type: String,
    default: '',
  },
  confirmText: {
    type: String,
    default: '确定',
  },
  cancelText: {
    type: String,
    default: '取消',
  },
  type: {
    // 警告(waring) 还是错误(danger)状态
    type: String,
    default: 'waring',
  },
  isConfirmDisabled: {
    type: Boolean,
    default: false,
  },
  isCancelDisabled: {
    type: Boolean,
    default: false,
  },
});

const dialogVisible = computed({
  get() {
    return props.visible;
  },
  set(v) {
    emit('update:visible', v);
  },
});
const onConfirm = () => {
  dialogVisible.value = false;
  emit('confirm');
};
const onCancel = () => {
  dialogVisible.value = false;
  emit('cancel');
};
</script>

<style lang="scss">
.message-box-delete {
  .my-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    .left {
      display: flex;
      align-items: center;
      gap: 8px;
    }
  }
  .content {
    margin-bottom: 24px;
    display: inline-block;
  }

  .el-overlay-dialog {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .el-dialog {
    margin-top: 0 !important;
  }
  .el-dialog__close {
    color: #666 !important;
  }
}
</style>

不使用render

import { h, createApp, nextTick, ref } from 'vue';
import MyMessageBox from './MyMessageBox.vue';

let messageBoxInstance = null;

const QWMessageBox = (options) => {
  return new Promise((resolve) => {
    if (!messageBoxInstance) {
      const div = document.createElement('div');
      document.body.appendChild(div);

      const visible = ref(false);

      const app = createApp({
        setup() {
          const toggleVisible = (value) => {
            visible.value = value;
            if (!value) {
              setTimeout(() => {
                app.unmount();
                div.remove();
                messageBoxInstance = null;
              }, 300);
            }
          };

          const handleConfirm = () => {
            resolve();
            toggleVisible(false);
          };

          const handleCancel = () => toggleVisible(false);

          return () =>
            h(MyMessageBox, {
              ...options,
              visible,
              'onUpdate:visible': toggleVisible,
              onConfirm: handleConfirm,
              onCancel: handleCancel,
            });
        },
      });

      app.mount(div);
      messageBoxInstance = { app, visible };
    }

    nextTick(() => {
      messageBoxInstance.visible.value = true;
    });
  });
};

export default QWMessageBox;

在这个例子中,setup 函数返回了一个箭头函数 () => h(...),这个箭头函数就是组件的渲染逻辑。Vue 3 会自动将这个返回的函数视为 render 函数,并调用它来生成 VNode。

显示使用render

const app = createApp({
  setup() {
    const visible = ref(false);

    const toggleVisible = (value) => {
      visible.value = value;
      if (!value) {
        nextTick(() => {
          app.unmount();
          div.remove();
          messageBoxInstance = null;
        });
      }
    };

    const handleConfirm = () => {
      resolve();
      toggleVisible(false);
    };

    const handleCancel = () => toggleVisible(false);

    return {
      visible,
      toggleVisible,
      handleConfirm,
      handleCancel,
    };
  },
  render() {
    const { visible, toggleVisible, handleConfirm, handleCancel } = this;

    return h(MyMessageBox, {
      ...options,
      visible,
      'onUpdate:visible': toggleVisible,
      onConfirm: handleConfirm,
      onCancel: handleCancel,
    });
  },
});

app.mount(div);
messageBoxInstance = { app, visible };

具体使用

// 删除弹框
import QWMessageBox from '@/components/QWMessageBox/QWMessageBox';


  QWMessageBox({
    title: item.xxxx,
  }).then(() => {
   
  });

相关文章

网友评论

      本文标题:vue-删除弹框组件封装

      本文链接:https://www.haomeiwen.com/subject/xdomrjtx.html