vue命令式组件的封装

一、前言

  当Vue项目中ElementUI的confirm提示不满足我们的样式需求时,一般我们会修改全局样式,或者封装一个dialog弹窗组件用于消息的提示和操作。

  如果封装一个dialog作为组件引入,必然需要一个visible变量来控制显隐,是否显示确认、取消按钮的变量及它们的回调函数,如果一个页面需要二次提示的地方太多,那就会显得模版臃肿、需要维护的变量变多,不优雅,使用成本变高。

xml 复制代码
 <!-- 是否取消订单 -->  
 <tips-dialog :visible.sync="dialogVisible.cancelTips" title="确认取消该订单吗?" :on-submit-c-b="cancelOrder" />  
 <!-- 是否删除订单 -->  
 <tips-dialog :visible.sync="dialogVisible.removeTips" title="确认删除该订单吗?" :message="删除后将无法恢复。" :on-submit-c-b="deleteOrder" />  
 ···
 ···

  现在想让使用成本变低,可以考虑使用命令式组件的方式

二、命令式组件

命令式组件是通过编程的方式动态创建、挂载、销毁的

命令式组件的优点:

1、动态控制:可以根据用户行为或程序逻辑动态的创建和销毁组件。

2、灵活性:可以在代码任何部分创建组件爱你,并且可以动态传递参数或数据

3、代码隔离:有助于逻辑的封装和隔离

三、代码实践

弹窗vue模板

xml 复制代码
<template>  
  <div class="confirm-wrap">  
    <div class="main">  
      <div class="title">{{ title }}</div>  
      <p class="message">{{ message }}</p>  
      <div class="btn-grounp">  
        <button v-if="showCancelButton" class="cancel-btn" @click="$emit('cancel')">{{ cancelButtonText }}</button>  
        <button v-if="showConfirmButton" class="confirm-btn" @click="$emit('confirm')">{{ confirmButtonText }}</button>  
      </div>  
    </div>  
  </div>  
</template>

<style scoped lang="less">  
  .confirm-wrap {  
    position: fixed;  
    top: 0;  
    bottom: 0;  
    left: 0;  
    right: 0;  
    display: flex;  
    justify-content: center;  
    align-items: center;  
    background: rgba(0, 0, 0, 0.3);  
    .main {  
      width: 30%;  
      padding: 24px;  
      background: #fff;  
      border-radius: 3px;  
      .title {  
        color: #202d40;  
        font-size: 16px;  
      }  
      .message {  
        margin-top: 10px;  
        color: #899099;  
        font-size: 14px;  
      }  
      .btn-grounp {  
        display: flex;  
        justify-content: flex-end;  
        margin-top: 24px;  
      }  
      button {  
        box-sizing: border-box;  
        margin-left: 12px;  
        padding: 0px 22px;  
        font-size: 14px;  
        line-height: 32px;  
        cursor: pointer;  
      }  
      .confirm-btn {  
        color: #fff;  
        background: #006aff;  
      }  
      .cancel-btn {  
        color: #899099;  
        background: #fff;  
        border: 1px solid #edeef2;  
      }  
    }  
  }  
</style>

js部分,以$ygConfirm挂载到Vue的原型上

javascript 复制代码
import Vue from 'vue'  
import MessageBox from './index.vue'

const MessageBoxConstructor = Vue.extend(MessageBox)

const defualtOptions = {  
  confirmButtonText: '确定',  
  cancelButtonText: '取消',  
  showConfirmButton: true,  
  showCancelButton: true  
}

// 模拟elementUI的用法  
const confirm = function (message, title, options = {}) {  
  if (typeof title === Object && title!==null) {  
    options = title  
    title = ''
  }  
  options = { ...defualtOptions,  message, title , ...options)

  const instance = new MessageBoxConstructor({  
    data: options  
  })

  // 挂载到body上  
  instance.vm = instance.$mount()  
  document.body.appendChild(instance.vm.$el)

  // 销毁实例  
  const removeVM = () => {  
    instance.vm.$destroy()  
    document.body.removeChild(instance.vm.$el)  
  }

  // 监听确认和取消事件,由$emit触发  
  return new Promise((resolve, reject) => {  
    instance.vm.$on('confirm', () => {  
      resolve()  
      removeVM()  
    })  
    instance.vm.$on('cancel', () => {  
      reject()  
      removeVM()  
    })  
  })  
}

export default confirm

使用

javascript 复制代码
this.$ygConfirm('你好啊啊啊啊啊','test').then(()=>{
    console.log('点击了确认~')
}).catch(()=>{
    console.log('点击了取消~')
})

效果图

相关推荐
云浪7 小时前
Go 并发实战:从零实现一个高并发安全的任务调度器
javascript·后端·go
OpsEye15 小时前
大模型账单对账难:不同厂商 Token 统计口径差异怎么处理
javascript·ai编程
全栈项目管理程序猿15 小时前
ArcGIS JS 基础教程(32):体元系列 - VoxelSlice 体元切片
前端·javascript
流烟默17 小时前
SSE 实战:在 SpringBoot + Vue 项目中零依赖实现轻量级实时消息推送
vue.js·spring boot·后端·sse
Hilaku17 小时前
AI 流式输出都用 SSE,什么时候必须换 WebSocket?
前端·javascript·程序员
奇牙coding17 小时前
Codex CLI 升级后多文件编辑静默失效:config.yaml 枚举变更排查与修复指南
java·前端·javascript·ai
执子念的飞鱼18 小时前
纯前端预览 275 种文件格式是怎么做到的
前端·vue.js·react.js
不简说18 小时前
AI 帮你画模板、点一下就云打印:sv-print 这三个月都干了啥
前端·javascript·人工智能
大明二代19 小时前
从零构建 Mastra RAG MVP:DeepSeek、SiliconFlow 与 PostgreSQL/pgvector 实战
javascript·数据库·人工智能
结局无敌19 小时前
React Native for OpenHarmony 实战:三方库 react-native-paper 的鸿蒙化适配指南
javascript·人工智能·深度学习·react native·react.js·ecmascript·harmonyos