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('点击了取消~')
})

效果图

相关推荐
Jiaberrr16 分钟前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy40 分钟前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
Ylucius1 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
LvManBa1 小时前
Vue学习记录之六(组件实战及BEM框架了解)
vue.js·学习·rust
200不是二百1 小时前
Vuex详解
前端·javascript·vue.js
LvManBa1 小时前
Vue学习记录之三(ref全家桶)
javascript·vue.js·学习
深情废杨杨2 小时前
前端vue-父传子
前端·javascript·vue.js
工业互联网专业2 小时前
毕业设计选题:基于springboot+vue+uniapp的驾校报名小程序
vue.js·spring boot·小程序·uni-app·毕业设计·源码·课程设计
J不A秃V头A3 小时前
Vue3:编写一个插件(进阶)
前端·vue.js
司篂篂3 小时前
axios二次封装
前端·javascript·vue.js