magiccube-vue3
Version:
vue3-js版组件库
136 lines (120 loc) • 4.03 kB
JavaScript
import { ref, computed, Teleport, onUnmounted, watch, getCurrentInstance } from 'vue'
import * as utils from '../../utils/common'
const SideSlidePopup = {
props: {
modelValue: Boolean,
maskType: {
type: String,
default: 'dark'
},
top: {
type: [Number, String],
default: 0
},
zIndex: Number,
},
emits: ['close', 'click-mask', 'init'],
setup(props, { emit, slots }) {
const uuid = utils._uuid()
/* 动态锚点 */
const instance = getCurrentInstance()
const globalOptions = instance.appContext?.config?.globalProperties?.$ELEMENT
const TELEPORT_NAME = globalOptions.teleportName? `.${globalOptions.teleportName}` : 'body'
const handleClickMask = (e) => {
if(e.target !== e.currentTarget) return
emit('click-mask')
}
watch(() => props.modelValue, (newValue, oldValue) => newValue && emit('init'))
onUnmounted(() => {
/**
* 注销并移除下拉dom
*/
const target = document.getElementById(uuid)
target && target.parentNode.removeChild(target)
})
return () => (
<Teleport to={TELEPORT_NAME}>
<div id={uuid}
class={{
'mc-side-slide-panel': true,
'slide-in': props.modelValue,
'slide-out': !props.modelValue,
dark: props.maskType === 'dark',
white: props.maskType === 'white',
}}
style={{
top: props.top + 'px',
zIndex: props.zIndex,
}}
onClick={handleClickMask}>
{slots.default ? slots.default() : ''}
</div>
</Teleport>
)
}
}
const Slide = {
name: 'McSlide',
props: {
modelValue: Boolean,
title: {
type: String,
default: '温馨提示'
},
maskType: {
type: String,
default: 'dark'
},
width: [Number, String],
top: [Number, String],
zIndex: Number,
},
emits: ['update:modelValue', 'cancel'],
setup(props, { emit, slots }) {
const popupEl = ref(null)
const model = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
const handleCancel = () => {
model.value = false
emit('cancel')
}
return () => (
<SideSlidePopup ref={popupEl}
modelValue={props.modelValue}
maskType={props.maskType}
top={props.top}
zIndex={props.zIndex}
onClickMask={handleCancel}>
<div
class={{
'mc-slide': true,
'fade-in': props.modelValue,
'fade-out': !props.modelValue,
}}
style={{ width: props.width + 'px' }}>
<div class="mc-slide__header">
<span class="mc-slide__header--title">{props.title}</span>
<span class="mc-slide__header--close"
onClick={handleCancel}>
<img src={require('../../img/icon_close.svg')} />
</span>
</div>
<div class="mc-slide__content">
{slots.default ? slots.default() : ''}
</div>
</div>
</SideSlidePopup>
)
}
}
Slide.install = (app) => {
app.component(Slide.name, Slide)
}
const McSlide = Slide
export { McSlide, McSlide as default }