123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <template>
- <el-dialog custom-class="cip-dialog__wrapper"
- :title="title"
- :model-value="modelValue"
- :width="width"
- :close-on-click-modal="closeOnClickModal"
- :top="top"
- append-to-body
- :destroyOnClose="destroyOnClose"
- @close="$emit('close')"
- @update:modelValue="changeVisible"
- @opened="handleOpened">
- <slot></slot>
- <template v-slot:footer v-if="!$slots.footer && !showOnly">
- <div style="text-align:right">
- <el-button @click="cancel" :size="buttonSize" v-if="!waiting">{{cancelText}}</el-button>
- <el-button @click="confirm" type="primary" :size="buttonSize" :loading="waiting">{{confirmText}}</el-button>
- </div>
- </template>
- <template #footer v-else>
- <slot name="footer" :confirm="confirm" :loading="waiting"></slot>
- </template>
- </el-dialog>
- </template>
- <script>
- import { ref, defineComponent, isRef } from 'vue'
- import { ElDialog, ElButton } from 'element-plus'
- export default defineComponent({
- name: 'CipDialog',
- components: { ElDialog, ElButton },
- props: {
- title: String,
- modelValue: { default: false }, // 是否显示dialog
- onConfirm: { type: Function }, // Function(resolve,reject)
- beforeConfirm: { type: Function, default: () => {} }, // 触发表单验证前的值设置
- width: { // 设置dialog宽度
- default: '870px'
- },
- top: { default: '15vh' },
- closeOnClickModal: { // 点击遮罩层是否关闭dialog
- type: Boolean,
- default: false
- },
- showOnly: {
- default: false
- },
- buttonSize: { // 设置footer按钮大小
- default: 'small'
- },
- confirmText: { // 触发on-confirm方法的按钮文字
- default: '确认'
- },
- cancelText: { // 触发关闭dialog方法按钮的文字
- default: '取消'
- },
- destroyOnClose: { // 默认关闭时销毁dialog
- type: Boolean,
- default: true
- }
- },
- emits: ['update:modelValue', 'cancel', 'close'],
- setup (props, context) {
- const waiting = ref(false)
- const changeVisible = (val) => {
- context.emit('update:modelValue', val)
- }
- const handleOpened = () => {
- const vnodeList = context.slots.default?.() || []
- vnodeList.forEach(vnode => {
- if (isRef(vnode.ref?.r)) {
- // ref直接勇士ref的变量
- // eslint-disable-next-line no-unused-expressions
- vnode.ref?.r.value?.clearValidate()
- } else {
- // ref使用字符串
- // eslint-disable-next-line no-unused-expressions
- vnode.ref?.i?.refs[vnode.ref?.r ?? 'form']?.clearValidate?.()
- }
- })
- }
- const validElForm = async (vnodeList = [], validList = []) => {
- const vnodeListLen = vnodeList.length
- for (let i = 0; i < vnodeListLen; i++) {
- const vnode = vnodeList[i]
- if (isRef(vnode.ref?.r)) {
- // eslint-disable-next-line no-unused-expressions
- vnode.ref?.r.value?.validate((valid) => {
- validList.push(valid)
- })
- } else {
- // eslint-disable-next-line no-unused-expressions
- vnode.ref?.i?.refs[vnode.ref?.r ?? 'form']?.validate?.((valid) => {
- validList.push(valid)
- })
- }
- }
- return validList
- }
- const confirm = async () => {
- waiting.value = true
- // 校验方法暂不可用
- try {
- const validList = await validElForm(context.slots.default?.())
- if (!validList.includes(false)) {
- await new Promise((resolve, reject) => {
- if (typeof props.onConfirm === 'function') {
- props.onConfirm(resolve, reject)
- } else {
- throw new TypeError('onConfirm is not a function')
- }
- })
- changeVisible(false)
- } else {
- // 存在未通过验证的表单
- }
- } catch (e) {
- // 错误捕捉
- console.error(e)
- }
- waiting.value = false
- }
- const cancel = () => {
- changeVisible(false)
- context.emit('cancel')
- }
- return {
- waiting,
- changeVisible,
- handleOpened,
- confirm,
- cancel
- }
- }
- })
- </script>
- <style lang="less">
- .cip-dialog__wrapper{
- &.el-dialog{
- .el-dialog__header{
- border-bottom: 1px solid #ddd;
- }
- .el-dialog__body{
- max-height: 60vh;
- overflow-y: auto;
- overflow-x: hidden;
- padding-bottom: 12px;
- }
- .el-dialog__footer{
- border-top: 1px solid #ddd;
- }
- }
- }
- </style>
|