nutui-uniapp
Version:
京东风格的轻量级移动端 Uniapp、Vue3 组件库(支持小程序开发)
124 lines (108 loc) • 3.2 kB
text/typescript
import type { CSSProperties, SetupContext } from 'vue'
import { computed, onMounted, ref, watch } from 'vue'
import { CANCEL_EVENT, CLOSED_EVENT, OPENED_EVENT, PREFIX, UPDATE_VISIBLE_EVENT } from '../_constants'
import { funInterceptor, getMainClass } from '../_utils'
import type { DialogEmits, DialogProps } from './dialog'
import type { DialogOptions } from './type'
const componentName = `${PREFIX}-dialog`
export function useDialog(props: DialogProps, emit: SetupContext<DialogEmits>['emit']) {
const showPopup = ref(props.visible)
const dialogStatus = ref<DialogOptions>({
title: props.title,
content: props.content,
cancelText: props.cancelText,
okText: props.okText,
textAlign: props.textAlign,
footerDirection: props.footerDirection,
noFooter: props.noFooter,
noOkBtn: props.noOkBtn,
noCancelBtn: props.noCancelBtn,
transition: props.transition,
closeOnClickOverlay: props.closeOnClickOverlay,
okAutoClose: props.okAutoClose,
})
watch(() => props.title, title => dialogStatus.value.title = title)
const showDialog = (options: DialogOptions) => {
dialogStatus.value = {
title: options.title || props.title,
content: options.content || props.content,
cancelText: options.cancelText || props.cancelText,
okText: options.okText || props.okText,
okAutoClose: options.okAutoClose || props.okAutoClose,
textAlign: options.textAlign || props.textAlign,
footerDirection: options.footerDirection || props.footerDirection,
noFooter: options.noFooter || props.noFooter,
noOkBtn: options.noOkBtn || props.noOkBtn,
transition: options.transition || props.transition,
noCancelBtn: options.noCancelBtn || props.noCancelBtn,
closeOnClickOverlay: options.closeOnClickOverlay || props.closeOnClickOverlay,
}
showPopup.value = true
}
onMounted(() => {
if (props.closeOnPopstate) {
// #ifdef H5
window.addEventListener('popstate', () => {
closed('page')
})
// #endif
}
})
watch(
() => props.visible,
(value) => {
showPopup.value = value
if (value)
emit(OPENED_EVENT)
},
)
const classes = computed(() => {
return getMainClass(props, componentName)
})
function update(val: boolean) {
emit('update', val)
emit(UPDATE_VISIBLE_EVENT, val)
}
function closed(action?: string) {
funInterceptor(props.beforeClose, {
args: [action],
done: () => {
showPopup.value = false
update(false)
emit(CLOSED_EVENT)
},
})
}
function onCancel() {
emit(CANCEL_EVENT)
if (props.cancelAutoClose) {
showPopup.value = false
closed(CANCEL_EVENT)
}
}
function onOk() {
emit('ok')
if (props.okAutoClose)
closed('ok')
}
function onClickOverlay() {
if (props.closeOnClickOverlay)
closed('')
}
const contentStyle = computed(() => {
return {
textAlign: dialogStatus.value.textAlign,
} as CSSProperties
})
return {
contentStyle,
showPopup,
onClickOverlay,
onCancel,
onOk,
closed,
classes,
showDialog,
dialogStatus,
}
}