shu-c-view
Version:
rollup 打包vue@2.7组件库框架
257 lines (254 loc) • 7.33 kB
JavaScript
/**
* @desc 拖拽 dialog
*/
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 { drag as vDragDialog } from './el-drag-dialog/index.js';
/**
* @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 BaseDragDialog = function(Vue) {
return function(options = {}) {
// const that = Vue.prototype;
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({
directives: {
'v-drag-dialog': vDragDialog
},
provide() {
return {
getBaseDragDialog: 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();
}
},
directives: [{ name: 'v-drag-dialog' }]
},
[
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 { BaseDragDialog };