UNPKG

ship-view-ui-plus

Version:

A high quality UI components Library with Vue.js 3

258 lines (233 loc) 7.81 kB
import { createApp, h, getCurrentInstance } from 'vue'; import Modal from './modal.vue'; import Button from '../button/button.vue'; import Locale from '../../mixins/locale'; import { isClient } from '../../utils/index'; const prefixCls = 'ivu-modal-confirm'; Modal.newInstance = properties => { if (!isClient) return; const _props = properties || {}; const container = document.createElement('div'); document.body.appendChild(container); let _instance = null; const Instance = createApp({ mixins: [ Locale ], data () { return Object.assign({}, _props, { visible: false, width: 416, title: '', body: '', iconType: '', iconName: '', okText: undefined, cancelText: undefined, showCancel: false, loading: false, buttonLoading: false, scrollable: false, closable: false, closing: false // 关闭有动画,期间使用此属性避免重复点击 }); }, render () { let footerVNodes = []; if (this.showCancel) { footerVNodes.push(h(Button, { type: 'text', onClick: this.cancel }, () => this.localeCancelText)); } footerVNodes.push(h(Button, { type: 'primary', loading: this.buttonLoading, onClick: this.ok }, () => this.localeOkText)); // render content let body_render; if (this.render) { body_render = h('div', { class: `${prefixCls}-body ${prefixCls}-body-render` }, [this.render(h)]); } else { body_render = h('div', { class: `${prefixCls}-body` }, [ h('div', { innerHTML: this.body }) ]); } // when render with no title, hide head let head_render; if (this.title) { head_render = h('div', { class: `${prefixCls}-head` }, [ h('div', { class: this.iconTypeCls }, [ h('i', { class: this.iconNameCls }) ]), h('div', { class: `${prefixCls}-head-title`, innerHTML: this.title }) ]); } return h(Modal, Object.assign({}, _props, { width: this.width, scrollable: this.scrollable, closable: this.closable, ref: 'modal' }, { modelValue: this.visible, 'onUpdate:modelValue': (status) => this.visible = status, 'onOn-cancel': this.cancel }), () => h('div', { class: prefixCls }, [ head_render, body_render, h('div', { class: `${prefixCls}-footer` }, footerVNodes) ]) ); }, computed: { iconTypeCls () { return [ `${prefixCls}-head-icon`, `${prefixCls}-head-icon-${this.iconType}` ]; }, iconNameCls () { return [ 'ivu-icon', `ivu-icon-${this.iconName}` ]; }, localeOkText () { if (this.okText) { return this.okText; } else { return this.t('i.modal.okText'); } }, localeCancelText () { if (this.cancelText) { return this.cancelText; } else { return this.t('i.modal.cancelText'); } } }, methods: { cancel () { if (this.closing) return; this.$refs.modal.visible = false; this.buttonLoading = false; this.onCancel(); this.remove(); }, ok () { if (this.closing) return; if (this.loading) { this.buttonLoading = true; } else { this.$refs.modal.visible = false; this.remove(); } this.onOk(); }, remove () { this.closing = true; setTimeout(() => { this.closing = false; this.destroy(); }, 300); }, destroy () { Instance.unmount(); document.body.removeChild(container); this.onRemove(); }, onOk () {}, onCancel () {}, onRemove () {} }, created () { _instance = getCurrentInstance(); } }); Instance.mount(container); const modal = _instance.refs.modal; return { show (props) { modal.$parent.showCancel = props.showCancel; modal.$parent.iconType = props.icon; switch (props.icon) { case 'info': modal.$parent.iconName = 'ios-information-circle'; break; case 'success': modal.$parent.iconName = 'ios-checkmark-circle'; break; case 'warning': modal.$parent.iconName = 'ios-alert'; break; case 'error': modal.$parent.iconName = 'ios-close-circle'; break; case 'confirm': modal.$parent.iconName = 'ios-help-circle'; break; } if ('width' in props) { modal.$parent.width = props.width; } if ('closable' in props) { modal.$parent.closable = props.closable; } if ('title' in props) { modal.$parent.title = props.title; } if ('content' in props) { modal.$parent.body = props.content; } if ('okText' in props) { modal.$parent.okText = props.okText; } if ('cancelText' in props) { modal.$parent.cancelText = props.cancelText; } if ('onCancel' in props) { modal.$parent.onCancel = props.onCancel; } if ('onOk' in props) { modal.$parent.onOk = props.onOk; } // async for ok if ('loading' in props) { modal.$parent.loading = props.loading; } if ('scrollable' in props) { modal.$parent.scrollable = props.scrollable; } // notice when component destroy modal.$parent.onRemove = props.onRemove; modal.visible = true; }, remove () { modal.visible = false; modal.$parent.buttonLoading = false; modal.$parent.remove(); }, component: modal }; }; export default Modal;