vue命令式组件的封装

一、前言

当Vue项目中ElementUIconfirm提示不满足我们的样式需求时,一般我们会修改全局样式,或者封装一个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('点击了取消~')
})

效果图

相关推荐
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203982 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
supermapsupport4 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
m0_748254884 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
噢,我明白了5 小时前
同源策略:为什么XMLHttpRequest不能跨域请求资源?
javascript·跨域
sanguine__5 小时前
APIs-day2
javascript·css·css3
苹果醋36 小时前
Golang的文件加密工具
运维·vue.js·spring boot·nginx·课程设计
关你西红柿子6 小时前
小程序app封装公用顶部筛选区uv-drop-down
前端·javascript·vue.js·小程序·uv
济南小草根6 小时前
把一个Vue项目的页面打包后再另一个项目中使用
前端·javascript·vue.js
小木_.6 小时前
【python 逆向分析某有道翻译】分析有道翻译公开的密文内容,webpack类型,全程扣代码,最后实现接口调用翻译,仅供学习参考
javascript·python·学习·webpack·分享·逆向分析