UNPKG

shu-c-view

Version:

rollup 打包vue@2.7组件库框架

208 lines (206 loc) 6.19 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 { h } from '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'])); /* 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, render(h) { let customClass = 'base-el-dialog'; if ( _has(this.$props, 'customClass') || _has(this.$props, 'custom-class') ) { customClass += ` ${_get(this.$props, 'customClass', '')} ${_get( this.$props, 'custom-class', '' )}`; } contentNode = h(); if (_has(options.component, 'render')) { contentNode = h(options.component); } else if (_has(options.component(), 'el')) { const detailOption = options.component(); contentNode = h(detailOption.el, _omit(detailOption, ['el']), [ _get(detailOption, 'children') ]); // ref 对象无法获取 } else { contentNode = options.component(); } return h( 'el-dialog', { class: { 'base-dialog__wrapper': true, [options.ctCls]: options.ctCls }, props: _assign( { // destroyOnClose: true, title: '详情', visible: this.visible, customClass }, _omit(this.$props, ['listeners', 'customClass']), {} ), on: { open: () => { if (_has(options, 'listeners.open')) { options.listeners.open(); } }, opened: () => { if (_has(options, 'listeners.opened')) { options.listeners.opened(); } }, close: () => { this.visible = false; if (_has(options, 'listeners.close')) { options.listeners.close(); } }, closed: () => { if (options.isDestroy) { this.$destroy(); if (_has(this, '$el')) { this.$el.remove(); } } else if (_has(options, 'listeners.closed')) { options.listeners.closed(); } } } }, [ contentNode, h('template', { slot: 'title' }, this.appendTitle()), h('template', { slot: 'footer' }, this.appendFooter()) ] ); } }); const instance = new VueModal({ propsData: options, data() { return { visible: false }; }, created() { this.$nextTick(() => { document.body.appendChild(instance.$mount().$el); }); }, methods: { // 详情组件引用 getContentNode() { return contentNode.componentInstance; }, // 打开 open() { setTimeout(() => { this.visible = true; }, 0); }, // 关闭 close() { setTimeout(() => { this.visible = false; }, 0); }, // 关闭(销毁实例) closeDialog() { if (_has(options, 'listeners.close')) { options.listeners.close(); } setTimeout(() => { instance.$destroy(); if (_has(instance, '$el')) { instance.$el.remove(); } }, 0); }, // Dialog 标题区的内容 appendTitle() { return _has(this.$props, 'slotNode.title') ? [this.$props.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(this.$props, 'slotNode.footer') ? _concat([this.$props.slotNode.footer(h)], buttonsVNode) : _concat([], buttonsVNode); } } }); /* if (_has(options, 'container')) { options.container.appendChild(instance.$mount().$el); } */ // document.body.appendChild(instance.$mount().$el); return instance; }; }; export { BaseDialog };