UNPKG

shu-c-view

Version:

rollup 打包vue@2.7组件库框架

252 lines (250 loc) 7.2 kB
/** * @desc 对话框 */ import _assign from 'lodash/assign'; import _omit from 'lodash/omit'; import _keys from 'lodash/keys'; import _has from 'lodash/has'; import _get from 'lodash/get'; import _concat from 'lodash/concat'; import _isFunction from 'lodash/isFunction'; import { h } from 'vue'; import Render from './render.vue'; // import { useRoute, useRouter } from 'vue-router/composables'; /** * @typedef {Object} options - 选项配置对象 * @property {Object} component - 组件对象 * @property {Object} container - html 节点容器 */ /** * @param {options} options - 选项配置 * @example * mounted(){ * this.dialogInstance = this.$baseDialog({component: Detail,container: this.$el,title: '添加',slotNode: {}}); * }, * methods: { * onOpenBaseDialog() { * this.dialogInstance.open(); * } * } */ const BaseDialog = function(Vue) { return function(options = {}) { // const that = this; // let contentNode = null; const optionsKey = _keys( _omit(options, [ '$route', '$router', 'slotNode', 'buttons', 'component', 'listeners', 'ctCls', 'isDestroy', 'title', 'customClass', 'visible', 'appendToBody', 'modalAppendToBody', 'destroyOnClose' ]) ); /* const $route = useRoute(); const $router = useRouter(); 如果在具体某个方法中创建的弹框对象这里获取router对象会报错 */ const VueModal = Vue.extend({ provide() { return { getBaseDialog: this }; }, // router: that.$router, vue@2.7版本弃用 // store: that.$store, vue@2.7版本弃用-2.7版本弃用vuex改用pinia router: options.$router, // vue2.7版本,传递到弹框的详情组件中使用:const { $route, $router } = getCurrentInstance().proxy; route: options.$route, props: optionsKey, data() { return { visible: false, curTitle: options.title || '提示' }; }, methods: { // Dialog 标题区的内容 appendTitle() { return _has(options, 'slotNode.title') ? [options.slotNode.title(h)] : []; }, // Dialog 按钮操作区的内容 appendFooter() { const buttonsVNode = []; for ( let i = 0, len = _get(options, 'buttons', []).length; i < len; i += 1 ) { const option = options.buttons[i]; buttonsVNode.push( h( 'el-button', { props: _get(option, 'props', function() { return {}; })(), on: option.on }, [option.text] ) ); } return _has(options, 'slotNode.footer') ? _concat([options.slotNode.footer(h)], buttonsVNode) : _concat([], buttonsVNode); }, setTitle(text) { this.curTitle = text; } }, render(h) { return h( 'el-dialog', { class: { 'base-dialog__wrapper': true, [options.ctCls]: options.ctCls }, props: _assign( { visible: this.visible, customClass: this.curCustomClass, title: this.curTitle, destroyOnClose: false, appendToBody: false, modalAppendToBody: true }, this.$props ), on: { 'update:visible': status => { this.visible = status; }, open: () => { if (_has(options, 'listeners.open')) { options.listeners.open(); } }, opened: () => { if (_has(options, 'listeners.opened')) { options.listeners.opened(); } }, close: () => { if (_has(options, 'listeners.close')) { options.listeners.close(); } }, closed: () => { if (_has(options, 'listeners.closed')) { options.listeners.closed(); } this.destroyedDialog(); } } }, [ this.comFun, h('template', { slot: 'title' }, this.appendTitle()), h('template', { slot: 'footer' }, this.appendFooter()) ] ); } }); const instance = new VueModal({ propsData: options, data() { this.readyPromise = null; this.readyPromiseResolve = null; this.curCustomClass = 'base-el-dialog'; this.comFun = null; this.isDestroy = true; return {}; }, created() { if (_isFunction(options.component)) { const component = options.component(); if (_has(component, 'el')) { this.comFun = h(Render, {}, [ h(component.el, _omit(component, ['el']), [ _get(component, 'children') ]) // ref 对象无法获取 ]); } else { this.comFun = h(Render, {}, [options.component]); } } if (_has(options.component, 'render')) { this.comFun = h(Render, {}, [h(options.component)]); } if (_has(options, 'customClass')) { this.curCustomClass += ` ${_get(options, 'customClass', '')}`; } this.readyPromise = new Promise(resolve => { this.readyPromiseResolve = resolve; }); this.$nextTick(() => { document.body.appendChild(instance.$mount().$el); this.readyPromiseResolve(); }); }, beforeDestroy() { this.readyPromise = undefined; this.readyPromiseResolve = undefined; this.comFun = undefined; }, methods: { ready() { return this.readyPromise; }, // 详情组件引用 getContentNode() { return this.comFun.componentInstance.$children[0]; }, // 打开 open() { this.ready() .then(() => { this.visible = true; return true; }) .catch(() => { // }); }, // 关闭 close() { this.$children[0].handleClose(); }, // 关闭 closeDialog() { this.close(); }, // 销毁实例 destroyedDialog() { setTimeout(() => { instance.$destroy(); if (_has(instance, '$el')) { instance.$el.remove(); } }, 0); } } }); /* if (_has(options, 'container')) { options.container.appendChild(instance.$mount().$el); } */ // document.body.appendChild(instance.$mount().$el); return instance; }; }; export { BaseDialog };