nimble-ui
Version:
203 lines (199 loc) • 6.7 kB
JavaScript
import { copyProper, callFn, getBackData, extend } from 'nimble-lib';
import Service from '../services';
import MountCom from '../../_commons/helpers/mountCom';
import { POPUP_EVENT } from '../../_commons/constant';
let mixins = function(vue) {
vue.mixin({
beforeDestroy() {
this.$emit('destroyPopupCore');
}
});
};
export class PopupCore extends Service {
name = 'PopupCore';
_mountCom = null;
/**
* 不使用use的时候需要传Vue构建函数
* @param {Function} Vue Vue构建函数
* @param {Object} options 选项
* @memberof PopupService
*/
constructor(Vue, options) {
super(options);
this.setDefaultOptions(options);
this._initMountCom(Vue);
}
/**
* 初始化浮窗
*
* @param {IPopupOptions} [options] 浮窗参数
* @param {Function} [closePopupBack] 关闭时的回调
* @returns {KidPopup}
* @memberof PopupService
*/
_instPopup(options) {
let _that = this;
options = _that.getOptions(options);
let _opts = extend({}, options);
_opts.props = copyProper(true, {
maskFlag: '',
props: '',
content: '',
isOpen: true,
isShow: true,
maskCloseFlag: '',
isCloseBtn: '',
alignCla: '',
wrapCla: '',
transition: '',
transitionCls: '',
routerOption: '',
isHeight: false,
scrollEl: '',
isDisableScroll: ''
}, options);
return new Promise((resolve, reject) => {
com(options.content).then((content) => {
_opts.props.content = content;
getBackData(options.popupComponent).then((res) => {
let _popup = _that._mountCom.instCom(res, _opts);
resolve(_popup);
}, reject);
});
});
/**
* 处理组件,兼容ts
* @param {*} content vue组件或组件异步函数
* @return {Promise}
*/
function com(content) {
if (options.content && options.content.prototype && options.content.prototype.$mount) {
return new Promise((resolve, reject) => {
resolve(content);
});
}
return getBackData(content);
}
}
/**
* 创建弹窗及在弹窗插入组件
*
* @template T
* @param {Type<T>} component 组件
* @param {IPopupOptions} [options] 弹窗及组件选项
* @param {Function} cb 关闭时的回调
* @returns {IInstComponentData<T>}
* @memberof PopupService
*/
createPopup(component, options, cb) {
let _that = this;
let _options = _that.getOptions(options, {
content: component
});
return new Promise((resolve, reject) => {
_that._instPopup(_options).then((_popup) => {
let _com = _popup.$refs.hook_is;
let res = {
component: _com,
popup: _popup,
updateProps(props) { // 更新组件props参数
if (_popup) {
_popup.$data.myProps = Object.assign({}, _popup.$data.myProps, props);
}
},
updateData (data) { // 更新组件data参数
_com = _popup.$refs.hook_is;
console.warn('请不要使用updateData修改数据');
_com && _that._mountCom.updataProps(_com.$data, data);
},
show() { // 显示弹窗
_popup && _popup.show();
},
hide() { // 隐藏弹窗
_popup && _popup.hide();
},
closePopup() { // 关闭带过度效果
_popup && _popup.closePopup();
},
close() { // 直接关闭不带过渡效果
_popup && _popup.close();
}
};
if (_popup && _popup.$parent) {
_popup.$parent.$once('destroyPopupCore', _closePopup);
}
_popup.$on(POPUP_EVENT.CLOSE, () => { // 直接关闭不带过渡效果
_closePopup();
});
if (_com) {
if (_options && _options.data instanceof Object) {
res.updateData(_options.data);
}
resolve(res);
} else {
setTimeout(() => {
if (_options && _options.data instanceof Object) {
res.updateData(_options.data);
}
res.component = _popup.$refs.hook_is;
resolve(res);
});
}
/**
* 关闭弹窗
*
*/
function _closePopup() {
if (_popup) {
if (_popup.$parent) {
_popup.$parent.$off('destroyPopupCore', _closePopup);
}
let el = _popup.$el;
_popup.$destroy();
let pEl = el.parentNode;
pEl && pEl.removeChild(el);
callFn(cb);
}
res.popup = null;
res.component = null;
_popup = null;
_com = null;
}
}, reject);
});
}
/**
* 设置_mountCom
*
* @param {any} Vue vue
* @memberof PopupService
*/
_initMountCom(Vue) {
let _that = this;
if (!_that._mountCom) {
let cre = new MountCom(Vue);
if (Vue) {
callFn(mixins, [Vue]);
mixins = null;
}
cre._getParent = () => {
return _that._getParent && _that._getParent();
};
_that._mountCom = cre;
} else {
_that._mountCom.setVue(Vue);
}
}
/**
* 安装
*
* @param {Vue} Vue Vue
* @param {Object} options 初始化选项
* @memberof PopupService
*/
install(Vue, options) {
let _that = this;
_that._initMountCom(Vue);
super.install(Vue, options);
}
}