UNPKG

nimble-ui

Version:
203 lines (199 loc) 6.7 kB
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); } }