@truenewx/tnxvue3
Version:
互联网技术解决方案:Vue3扩展支持
264 lines (248 loc) • 10.7 kB
JavaScript
// tnxbsv.js
import tnxjq from '@truenewx/tnxcore/src/tnxjq';
import tnxvue from '../tnxvue.js';
import * as BootstrapVue from 'bootstrap-vue-next';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue-next/dist/bootstrap-vue-next.css';
import './tnxbsv.css';
import Alert from './alert/Alert.vue';
import Button from './button/Button.vue';
import Cascader from './cascader/Cascader.vue';
import Dialog from './dialog/Dialog.vue';
import EnumSelect from './enum-select/EnumSelect.vue';
import Form from './form/Form.vue';
import FormGroup from './form/FormGroup.vue';
import LoadingIcon from './loading-icon/LoadingIcon.vue';
import LoadingOverlay from './loading-overlay/LoadingOverlay.vue';
import Paged from './paged/Paged.vue';
import Progress from './progress/Progress.vue';
import QueryForm from './query-form/QueryForm.vue';
import QueryTable from './query-table/QueryTable.vue';
import RegionCascader from './region-cascader/RegionCascader.vue';
import Select from './select/Select.vue';
import SubmitForm from './submit-form/SubmitForm.vue';
import TagsInput from './tags-input/TagsInput.vue';
import Upload from './upload/Upload.vue';
export const build = tnxvue.build;
export default build('tnxbsv', () => {
const components = Object.assign({}, tnxvue.components, {
Alert,
Button,
Cascader,
Dialog,
EnumSelect,
Form,
FormGroup,
LoadingIcon,
Paged,
Progress,
QueryForm,
QueryTable,
RegionCascader,
Select,
SubmitForm,
TagsInput,
Upload,
});
const tnxbsv = Object.assign({}, tnxjq, tnxvue, {
libs: Object.assign({}, tnxjq.libs, tnxvue.libs, {BootstrapVue}),
components,
componentDefaultApp: undefined, // 组件的默认app,从服务端获取数据的组件以此为远程请求的默认app
dialogInstances: [], // 对话框堆栈
dialog(content, title, buttons, options, contentProps) {
// 弹出之前关闭所有加载框
this.hideLoading();
let id = new Date().getTime();
let containerId = 'dialog-container-' + id;
let componentDefinition = Object.assign({}, Dialog,);
let rootProps = Object.assign({}, options, {
modelValue: true,
id: id,
container: '#' + containerId,
title,
content,
contentProps,
buttons,
});
let dialogVm = window.tnx.createVueInstance(componentDefinition, null, rootProps);
const dialogContainer = document.createElement('div');
dialogContainer.className = 'tnxbsv-dialog-container';
dialogContainer.id = containerId;
document.body.appendChild(dialogContainer);
let dialog = dialogVm.mount(dialogContainer);
dialog.onHidden = this.util.function.after(dialog.onHidden, () => {
dialogVm.unmount();
window.tnx.dialogInstances.remove(dialog);
document.body.removeChild(dialogContainer);
});
window.tnx.dialogInstances.push(dialog);
return dialog;
},
closeDialog(all) {
return new Promise((resolve) => {
if (window.tnx.dialogInstances.length) {
let dialog = window.tnx.dialogInstances.pop();
while (dialog) {
const originalClose = dialog.close;
if (originalClose) {
dialog.close = function (cb) {
originalClose.call(this, () => {
if (typeof cb === 'function') {
cb();
}
resolve();
});
};
dialog.close();
} else {
resolve();
}
if (all) {
dialog = window.tnx.dialogInstances.pop();
} else {
break;
}
}
} else {
resolve();
}
});
},
_closeMessage() {
this.hideLoading();
this.removeToast();
},
alert(message, title, options) {
return new Promise(resolve => {
let buttons = tnxvue.getDefaultDialogButtons('primary', close => {
return resolve(close);
});
message =
`<div class="tnxbsv-dialog-alert"><i class="bi bi-exclamation-circle-fill"></i><div>${message}</div></div>`;
this.dialog(message, title, buttons, options);
});
},
success(message, options) {
return new Promise(resolve => {
let buttons = tnxvue.getDefaultDialogButtons('primary', close => {
return resolve(close);
});
message =
`<div class="tnxbsv-dialog-success"><i class="bi bi-check-circle-fill"></i><div>${message}</div></div>`;
this.dialog(message, '成功', buttons, options);
});
},
error(message, options) {
return new Promise(resolve => {
let buttons = tnxvue.getDefaultDialogButtons('primary', close => {
return resolve(close);
});
message =
`<div class="tnxbsv-dialog-error"><i class="bi bi-x-circle-fill"></i><div>${message}</div></div>`;
this.dialog(message, '错误', buttons, options);
});
},
confirm(message, title = '确认', options) {
return new Promise(resolve => {
let buttons = tnxvue.getDefaultDialogButtons('confirm', yes => {
return resolve(yes);
});
message =
`<div class="tnxbsv-dialog-confirm"><i class="bi bi-question-circle-fill"></i><div>${message}</div></div>`;
this.dialog(message, title, buttons, options);
});
},
toast(message, timeout, options = {}) {
this._closeMessage();
const div = document.createElement('div');
document.body.appendChild(div);
return new Promise(resolve => {
const Vue = window.tnx.libs.Vue;
const ToastComponent = {
components: {
BToast: BootstrapVue.BToast
},
setup() {
const visible = Vue.ref(true);
Vue.onMounted(() => {
setTimeout(() => {
visible.value = false;
// 延迟移除组件,确保动画效果完成
setTimeout(() => {
window.tnx.toastInstance?.unmount();
try {
document.body.removeChild(div);
} catch (e) {
// 忽略异常
}
resolve();
}, 500);
}, timeout || 1500);
});
return {visible};
},
render() {
return Vue.h(BootstrapVue.BToast, {
modelValue: this.visible,
variant: options.type || 'success',
static: true,
noCloseButton: true,
class: 'position-fixed',
style: {
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
zIndex: window.tnx.util.dom.minTopZIndex(),
}
}, () => message);
}
};
const instance = window.tnx.createVueInstance(ToastComponent);
instance.mount(div);
window.tnx.toastInstance = instance;
});
},
removeToast() {
if (window.tnx.toastInstance) {
window.tnx.toastInstance.unmount();
try {
document.body.removeChild(window.tnx.toastInstance._container);
} catch (e) {
// 忽略异常
}
window.tnx.toastInstance = null;
}
},
showLoading(message = '', options) {
this._closeMessage();
let div = document.createElement('div');
div.classList.add('tnxbsv-loading-overlay')
document.body.appendChild(div);
let instance = window.tnx.createVueInstance(LoadingOverlay, null, {message});
instance.mount(div);
window.tnx.loadingInstances.push(instance);
window.tnx.app.eventBus.emit('tnx.showLoading', options);
},
loadingInstances: [],
hideLoading() {
if (window.tnx.loadingInstances.length) {
window.tnx.loadingInstances.forEach(instance => {
instance.unmount();
});
window.tnx.loadingInstances.length = 0;
// 删除所有div.tnxbsv-loading-overlay
document.body.querySelectorAll('div.tnxbsv-loading-overlay').forEach(div => {
document.body.removeChild(div);
});
}
},
closeLoading() {
this.hideLoading();
},
});
tnxbsv.install = tnxbsv.util.function.around(tnxbsv.install, function (install, vm) {
install.call(tnxbsv, vm);
vm.use(BootstrapVue.createBootstrap());
});
return tnxbsv;
});