|
|
<template>
|
|
|
<view>
|
|
|
<wd-popup
|
|
|
transition="zoom-in"
|
|
|
v-model="show"
|
|
|
:close-on-click-modal="closeOnClickModal"
|
|
|
:lazy-render="lazyRender"
|
|
|
custom-class="wd-message-box"
|
|
|
@click-modal="toggleModal('modal')"
|
|
|
:z-index="zIndex"
|
|
|
:duration="200"
|
|
|
>
|
|
|
<view :class="rootClass">
|
|
|
<!--内容部分-->
|
|
|
<view :class="bodyClass">
|
|
|
<!--公共title-->
|
|
|
<view v-if="title" class="wd-message-box__title">
|
|
|
{{ title }}
|
|
|
</view>
|
|
|
<!--其它类型-->
|
|
|
<view class="wd-message-box__content">
|
|
|
<!--prompt类型-->
|
|
|
<block v-if="type === 'prompt'">
|
|
|
<!--输入框-->
|
|
|
<wd-input v-model="inputValue" :type="inputType" size="large" :placeholder="inputPlaceholder || '请输入'" @input="inputValChange" />
|
|
|
<!--错误提示-->
|
|
|
<view v-if="showErr" class="wd-message-box__input-error">
|
|
|
{{ inputError || '输入的数据不合法' }}
|
|
|
</view>
|
|
|
</block>
|
|
|
<!--使用插槽-->
|
|
|
<slot v-if="useSlot"></slot>
|
|
|
<!--使用文本-->
|
|
|
<block v-else>{{ msg }}</block>
|
|
|
</view>
|
|
|
</view>
|
|
|
<!--action按钮组合-->
|
|
|
<view :class="`wd-message-box__actions ${showCancelButton ? 'wd-message-box__flex' : 'wd-message-box__block'}`">
|
|
|
<wd-button type="info" block v-if="showCancelButton" custom-style="margin-right: 16px;" @click="toggleModal('cancel')">
|
|
|
{{ cancelButtonText || '取消' }}
|
|
|
</wd-button>
|
|
|
<wd-button block @click="toggleModal('confirm')">
|
|
|
{{ confirmButtonText || '确定' }}
|
|
|
</wd-button>
|
|
|
</view>
|
|
|
</view>
|
|
|
</wd-popup>
|
|
|
</view>
|
|
|
</template>
|
|
|
<script lang="ts">
|
|
|
export default {
|
|
|
name: 'wd-message-box',
|
|
|
options: {
|
|
|
virtualHost: true,
|
|
|
addGlobalClass: true,
|
|
|
styleIsolation: 'shared'
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import { computed, inject, ref, watch } from 'vue'
|
|
|
import type { MessageOptions, MessageType } from './types'
|
|
|
import { defaultOptions, messageDefaultOptionKey } from '.'
|
|
|
import { isDef } from '../common/util'
|
|
|
|
|
|
interface Props {
|
|
|
useSlot?: boolean
|
|
|
selector?: string
|
|
|
customClass?: string
|
|
|
}
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
useSlot: false,
|
|
|
customClass: '',
|
|
|
selector: ''
|
|
|
})
|
|
|
|
|
|
const rootClass = computed(() => {
|
|
|
return `wd-message-box__container ${props.customClass}`
|
|
|
})
|
|
|
|
|
|
const bodyClass = computed(() => {
|
|
|
return `wd-message-box__body ${!title.value ? 'is-no-title' : ''} ${type.value === 'prompt' ? 'is-prompt' : ''}`
|
|
|
})
|
|
|
|
|
|
const messageOptionKey = props.selector ? messageDefaultOptionKey + props.selector : messageDefaultOptionKey
|
|
|
const messageOption = inject(messageOptionKey, ref<MessageOptions>(defaultOptions)) // message选项
|
|
|
|
|
|
/**
|
|
|
* 消息文案
|
|
|
*/
|
|
|
const msg = ref<string>('')
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
|
let onConfirm: Function | null = null
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
|
let onCancel: Function | null = null
|
|
|
const show = ref<boolean>(false)
|
|
|
/**
|
|
|
* 标题
|
|
|
*/
|
|
|
const title = ref<string>('')
|
|
|
/**
|
|
|
* 是否展示取消按钮
|
|
|
*/
|
|
|
const showCancelButton = ref<boolean>(false)
|
|
|
/**
|
|
|
* 是否支持点击蒙层进行关闭,点击蒙层回调传入的action为'modal'
|
|
|
*/
|
|
|
const closeOnClickModal = ref<boolean>(true)
|
|
|
/**
|
|
|
* 确定按钮文案
|
|
|
*/
|
|
|
const confirmButtonText = ref<string>('')
|
|
|
/**
|
|
|
* 取消按钮文案
|
|
|
*/
|
|
|
const cancelButtonText = ref<string>('')
|
|
|
|
|
|
/**
|
|
|
* 弹框类型
|
|
|
*/
|
|
|
const type = ref<MessageType>('alert')
|
|
|
|
|
|
/**
|
|
|
* 当type为prompt时,输入框类型
|
|
|
*/
|
|
|
const inputType = ref<string>('text')
|
|
|
|
|
|
/**
|
|
|
* 当type为prompt时,输入框初始值
|
|
|
*/
|
|
|
const inputValue = ref<string | number>('')
|
|
|
|
|
|
/**
|
|
|
* 当type为prompt时,输入框placeholder
|
|
|
*/
|
|
|
const inputPlaceholder = ref<string>('')
|
|
|
|
|
|
/**
|
|
|
* 当type为prompt时,输入框正则校验,点击确定按钮时进行校验
|
|
|
*/
|
|
|
const inputPattern = ref<RegExp>()
|
|
|
|
|
|
/**
|
|
|
* 当type为prompt时,输入框校验函数,点击确定按钮时进行校验
|
|
|
*/
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
|
let inputValidate: Function | null = null
|
|
|
|
|
|
/**
|
|
|
* 当type为prompt时,输入框检验不通过时的错误提示文案
|
|
|
*/
|
|
|
const inputError = ref<string>('')
|
|
|
const showErr = ref<boolean>(false)
|
|
|
/**
|
|
|
* 弹窗层级
|
|
|
*/
|
|
|
const zIndex = ref<number>(99)
|
|
|
/**
|
|
|
* 弹层内容懒渲染,触发展示时才渲染内容
|
|
|
*/
|
|
|
const lazyRender = ref<boolean>(true)
|
|
|
|
|
|
// 监听options变化展示
|
|
|
watch(
|
|
|
() => messageOption.value,
|
|
|
(newVal: MessageOptions) => {
|
|
|
reset(newVal)
|
|
|
},
|
|
|
{
|
|
|
deep: true,
|
|
|
immediate: true
|
|
|
}
|
|
|
)
|
|
|
|
|
|
watch(
|
|
|
() => show.value,
|
|
|
(newValue) => {
|
|
|
resetErr(newValue)
|
|
|
},
|
|
|
{
|
|
|
deep: true,
|
|
|
immediate: true
|
|
|
}
|
|
|
)
|
|
|
|
|
|
/**
|
|
|
* @description 关闭消息框的统一主调 handle
|
|
|
* @param {'cancel' | 'confirm'} action
|
|
|
*/
|
|
|
function toggleModal(action: 'confirm' | 'cancel' | 'modal') {
|
|
|
// closeOnClickModal为false,此时点击蒙层没任何效果
|
|
|
if (action === 'modal' && !closeOnClickModal.value) {
|
|
|
return
|
|
|
}
|
|
|
// prompt类型的弹窗 文案没有通过校验,点击了确定按钮没有任何效果
|
|
|
if (type.value === 'prompt' && action === 'confirm' && !validate()) {
|
|
|
return
|
|
|
}
|
|
|
show.value = false
|
|
|
switch (action) {
|
|
|
case 'confirm':
|
|
|
onConfirm &&
|
|
|
onConfirm({
|
|
|
action: action,
|
|
|
value: inputValue.value
|
|
|
})
|
|
|
break
|
|
|
case 'cancel':
|
|
|
onCancel &&
|
|
|
onCancel({
|
|
|
action: action
|
|
|
})
|
|
|
break
|
|
|
default:
|
|
|
onCancel &&
|
|
|
onCancel({
|
|
|
action: 'modal'
|
|
|
})
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* @description 如果存在校验规则行为,则进行判断校验是否通过规则。默认不存在校验直接铜鼓。
|
|
|
* @return {Boolean} 是否通过校验
|
|
|
*/
|
|
|
function validate() {
|
|
|
if (inputPattern.value && !inputPattern.value.test(String(inputValue.value))) {
|
|
|
showErr.value = true
|
|
|
return false
|
|
|
}
|
|
|
if (typeof inputValidate === 'function') {
|
|
|
const validateResult = inputValidate(inputValue)
|
|
|
if (!validateResult) {
|
|
|
showErr.value = true
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
showErr.value = false
|
|
|
return true
|
|
|
}
|
|
|
/**
|
|
|
* @description show关闭时,销毁错误提示
|
|
|
* @param val
|
|
|
*/
|
|
|
function resetErr(val) {
|
|
|
if (val === false) {
|
|
|
showErr.value = false
|
|
|
}
|
|
|
}
|
|
|
function inputValChange(value: string | number) {
|
|
|
if (value === '') {
|
|
|
showErr.value = false
|
|
|
return
|
|
|
}
|
|
|
inputValue.value = value
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 重置message选项值
|
|
|
* @param option message选项值
|
|
|
*/
|
|
|
function reset(option: MessageOptions) {
|
|
|
if (option) {
|
|
|
title.value = isDef(option.title) ? option.title : title.value
|
|
|
showCancelButton.value = isDef(option.showCancelButton) ? option.showCancelButton : showCancelButton.value
|
|
|
show.value = option.show!
|
|
|
closeOnClickModal.value = option.closeOnClickModal!
|
|
|
confirmButtonText.value = option.confirmButtonText!
|
|
|
cancelButtonText.value = option.cancelButtonText!
|
|
|
msg.value = option.msg!
|
|
|
type.value = option.type!
|
|
|
inputType.value = option.inputType!
|
|
|
inputValue.value = option.inputValue!
|
|
|
inputPlaceholder.value = option.inputPlaceholder!
|
|
|
inputPattern.value = option.inputPattern!
|
|
|
inputValidate = option.inputValidate!
|
|
|
onConfirm = (option as any).onConfirm
|
|
|
onCancel = (option as any).onCancel
|
|
|
inputError.value = option.inputError!
|
|
|
showErr.value = option.showErr!
|
|
|
zIndex.value = option.zIndex!
|
|
|
lazyRender.value = option.lazyRender!
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
@import './index.scss';
|
|
|
</style>
|