shu-c-view
Version:
rollup 打包vue@2.7组件库框架
214 lines (211 loc) • 6.5 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 { h } from '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;
let contentNode = null;
const optionsKey = _keys(_omit(options, ['$route', '$router']));
/* 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,
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, // 设置为 true 会在拖动弹框点击关闭时重置到初始的位置,所以注释了,如果想销毁组件请设置 isDestroy: 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();
}
}
},
directives: [{ name: 'v-drag-dialog' }]
},
[
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 { BaseDragDialog };