将el-dialog封装成函数调用

1、 使用Vue实例化方法

javascript 复制代码
// MyDialog.js
import Vue from 'vue'
export const openFormDialog = function ({ props = {}, events = {} }) {
  const vm = new Vue({
    data () {
      return {
        form: {}
      }
    },
    render () {
      return (
        <el-dialog
          visible={true}
          {...{ props }}
          {...{ on: events }}
          onClose={() => handleEvent('close')}
        >
          <el-form label-width='80px'>
            <el-form-item label='活动名称'>
              <el-input v-model={this.form.name}></el-input>
            </el-form-item>
            <el-form-item label='活动区域'>
              <el-select v-model={this.form.region} placeholder='请选择活动区域'>
                <el-option label='区域一' value='shanghai'></el-option>
                <el-option label='区域二' value='beijing'></el-option>
              </el-select>
            </el-form-item>
          </el-form>
          <span slot='footer' class="dialog-footer">
            <el-button onClick={() => { handleEvent('cancel') } }>取 消</el-button>
            <el-button type="primary" onClick={() => handleEvent('confirm', this.form) }>确 定</el-button>
          </span>
        </el-dialog>
      )
    }
  }).$mount()

  const close = () => {
    document.body.removeChild(vm.$el)
    vm.$destroy()
  }

  const handleEvent = async (eventName, form) => {
    await events[eventName] && typeof events[eventName] === 'function' && events[eventName](form)
    close()
  }

  document.body.appendChild(vm.$el)
}

2、使用Vue.extend方法

javascript 复制代码
// MyDialog.vue
<template>
  <el-dialog
    :visible.sync="dialogVisible"
    v-bind="options.props"
    v-on="options.events"
  >
    <el-form label-width='80px'>
      <el-form-item label='活动名称'>
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label='活动区域'>
        <el-select v-model="form.region" placeholder='请选择活动区域'>
          <el-option label='区域一' value='shanghai'></el-option>
          <el-option label='区域二' value='beijing'></el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="onConfirm">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
export default {
  data () {
    return {
      dialogVisible: true,
      options: {
        props: {
          width: '30%'
        },
        events: {}
      },
      form: {}
    }
  },
  methods: {
    setAttrs (options) {
      this.options = { ...options }
    },
    async onConfirm () {
      await this.options.events.confirm && typeof this.options.events.confirm === 'function' && this.options.events.confirm(this.form)
      this.dialogVisible = false
    }
  }
}
</script>
javascript 复制代码
// MyDialog.js
import Vue from 'vue'
import Dialog from './VDialog.vue'
export const openFormDialog = function (options) {
  const DialogConstructor = Vue.extend(Dialog)
  const instance = new DialogConstructor()
  instance.setAttrs(options)
  instance.$mount()
  document.body.appendChild(instance.$el)
}

3、注册使用

javascript 复制代码
// main.js
import { openFormDialog } from './components/MyDialog.js'
Vue.prototype.$openFormDialog = openFormDialog
javascript 复制代码
// 调用方法
this.$openFormDialog({
   props: {
     title: '测试标题',
     width: '30%',
     beforeClose (done) {
       done()
     }
   },
   events: {
     close () {
       console.log('close')
     },
     cancel () {
       console.log('cancel')
     },
     confirm (form) {
       console.log(form)
     }
   }
 })

以上为简单例子,可根据场景进行优化,期望各位留言告知是否有更好的实现方法

相关推荐
Ruihong几秒前
你的 Vue 3 TS 类型声明,VuReact 会处理成什么样的 React?
vue.js·react.js·面试
heytoo几秒前
同一个模型,为什么结果差10倍?差的不是模型
前端·agent
霪霖笙箫2 分钟前
「JS全栈AI学习」九、Multi-Agent 系统设计:架构与编排
前端·面试·全栈
慕斯fuafua3 分钟前
CSS——定位
前端·css
Cache技术分享4 分钟前
384. Java IO API - Java 文件复制工具:Copy 示例完整解析
前端·后端
shadowcz0075 分钟前
Chrome Skills 来了:把你的 AI 提示词变成一键工具
前端·人工智能·chrome
踩着两条虫5 分钟前
VTJ核心引擎开源项目概览
前端·vue.js·低代码
Front思6 分钟前
解决 uniapp Dart Sass 2.0.0 弃用警告
前端·uni-app·sass
农夫山泉不太甜6 分钟前
CSS 新特性与冷门属性深度剖析
前端
Hy行者勇哥8 分钟前
Chrome 浏览器如何“网页长截图”和“网站打包成应用”
前端·chrome