init
This commit is contained in:
3
uni_modules/nutui-uni/components/transition/index.ts
Normal file
3
uni_modules/nutui-uni/components/transition/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './transition'
|
||||
export type * from './types'
|
||||
export * from './use-transition'
|
||||
62
uni_modules/nutui-uni/components/transition/transition.ts
Normal file
62
uni_modules/nutui-uni/components/transition/transition.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import { CLICK_EVENT } from '../_constants'
|
||||
import { commonProps, makeNumberProp, makeStringProp } from '../_utils'
|
||||
import type { NutAnimationName, NutAnimationtimingFunction } from './types'
|
||||
|
||||
export const transitionProps = {
|
||||
...commonProps,
|
||||
/**
|
||||
* @description 内置动画名称,可选值为 `fade` `fade-up` `fade-down` f`ade-left` `fade-right` `slide-up` `slide-down` `slide-left` `slide-right`
|
||||
*/
|
||||
name: makeStringProp<NutAnimationName>('fade'),
|
||||
/**
|
||||
* @description 是否展示过渡动画级
|
||||
*/
|
||||
show: Boolean,
|
||||
/**
|
||||
* @description 动画时长,单位为毫秒
|
||||
*/
|
||||
duration: makeNumberProp(300),
|
||||
/**
|
||||
* @description 动画函数
|
||||
*/
|
||||
timingFunction: makeStringProp<NutAnimationtimingFunction>('ease'),
|
||||
destroyOnClose: Boolean,
|
||||
/**
|
||||
* @description 进入动画前的类名
|
||||
*/
|
||||
enterFromClass: String,
|
||||
/**
|
||||
* @description 进入动画时的类名
|
||||
*/
|
||||
enterActiveClass: String,
|
||||
/**
|
||||
* @description 进入动画后的类名
|
||||
*/
|
||||
enterToClass: String,
|
||||
/**
|
||||
* @description 离开动画前的类名
|
||||
*/
|
||||
leaveFromClass: String,
|
||||
/**
|
||||
* @description 离开动画时的类名
|
||||
*/
|
||||
leaveActiveClass: String,
|
||||
/**
|
||||
* @description 离开动画后的类名
|
||||
*/
|
||||
leaveToClass: String,
|
||||
}
|
||||
|
||||
export const transitionEmits = {
|
||||
beforeEnter: () => true,
|
||||
enter: () => true,
|
||||
afterEnter: () => true,
|
||||
beforeLeave: () => true,
|
||||
leave: () => true,
|
||||
afterLeave: () => true,
|
||||
[CLICK_EVENT]: (evt: MouseEvent) => evt instanceof Object,
|
||||
}
|
||||
|
||||
export type TransitionProps = ExtractPropTypes<typeof transitionProps>
|
||||
export type TransitionEmits = typeof transitionEmits
|
||||
37
uni_modules/nutui-uni/components/transition/transition.vue
Normal file
37
uni_modules/nutui-uni/components/transition/transition.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { PREFIX } from '../_constants'
|
||||
import { transitionEmits, transitionProps } from './transition'
|
||||
import { useTransition } from './use-transition'
|
||||
|
||||
const props = defineProps(transitionProps)
|
||||
const emits = defineEmits(transitionEmits)
|
||||
const { display, classes, clickHandler, styles } = useTransition(props, emits)
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const componentName = `${PREFIX}-transition`
|
||||
export default defineComponent({
|
||||
name: componentName,
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view
|
||||
v-if="!props.destroyOnClose || display"
|
||||
:class="classes"
|
||||
:style="styles"
|
||||
@click="clickHandler"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './index';
|
||||
</style>
|
||||
16
uni_modules/nutui-uni/components/transition/types.ts
Normal file
16
uni_modules/nutui-uni/components/transition/types.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { defaultAnimations } from './use-transition'
|
||||
|
||||
export type TransitionName = keyof typeof defaultAnimations
|
||||
|
||||
export interface NutAnimation {
|
||||
enter: string
|
||||
leave: string
|
||||
}
|
||||
|
||||
export const nutAnimationName = ['fade', 'fade-up', 'fade-down', 'fade-left', 'fade-right', 'slide-up', 'slide-down', 'slide-left', 'slide-right', 'zoom', 'none'] as const
|
||||
export type NutAnimationName = (typeof nutAnimationName)[number]
|
||||
export const nutAnimationtimingFunction = ['linear', 'ease', 'ease-in', 'ease-in-out', 'ease-out', 'step-start', 'step-end'] as const
|
||||
export type NutAnimationtimingFunction = (typeof nutAnimationtimingFunction)[number]
|
||||
export interface NutAnimations {
|
||||
[key: string]: NutAnimation
|
||||
}
|
||||
189
uni_modules/nutui-uni/components/transition/use-transition.ts
Normal file
189
uni_modules/nutui-uni/components/transition/use-transition.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
import type { SetupContext } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { CLICK_EVENT, PREFIX } from '../_constants'
|
||||
import { getMainClass, getMainStyle } from '../_utils'
|
||||
import type { TransitionEmits, TransitionProps } from './transition'
|
||||
import type { NutAnimations } from './types'
|
||||
|
||||
export const defaultAnimations: NutAnimations = {
|
||||
'fade': {
|
||||
enter: 'nutFadeIn',
|
||||
leave: 'nutFadeOut',
|
||||
},
|
||||
'fade-up': {
|
||||
enter: 'nutFadeUpIn',
|
||||
leave: 'nutFadeUpOut',
|
||||
},
|
||||
'fade-down': {
|
||||
enter: 'nutFadeDownIn',
|
||||
leave: 'nutFadeDownOut',
|
||||
},
|
||||
'fade-left': {
|
||||
enter: 'nutFadeLeftIn',
|
||||
leave: 'nutFadeLeftOut',
|
||||
},
|
||||
'fade-right': {
|
||||
enter: 'nutFadeRightIn',
|
||||
leave: 'nutFadeRightOut',
|
||||
},
|
||||
'slide-up': {
|
||||
enter: 'nutSlideUpIn',
|
||||
leave: 'nutSlideDownOut',
|
||||
},
|
||||
'slide-down': {
|
||||
enter: 'nutSlideDownIn',
|
||||
leave: 'nutSlideUpOut',
|
||||
},
|
||||
'slide-left': {
|
||||
enter: 'nutSlideLeftIn',
|
||||
leave: 'nutSlideLeftOut',
|
||||
},
|
||||
'slide-right': {
|
||||
enter: 'nutSlideRightIn',
|
||||
leave: 'nutSlideRightOut',
|
||||
},
|
||||
'zoom': {
|
||||
enter: 'nutZoomIn',
|
||||
leave: 'nutZoomOut',
|
||||
},
|
||||
|
||||
}
|
||||
const componentName = `${PREFIX}-transition`
|
||||
|
||||
export function isKeyOfAnimations(value: string) {
|
||||
const keys = Object.keys(defaultAnimations)
|
||||
|
||||
return keys.includes(value)
|
||||
}
|
||||
|
||||
export interface IClassNames {
|
||||
enter: string
|
||||
enterActive: string
|
||||
enterTo: string
|
||||
leave: string
|
||||
leaveActive: string
|
||||
leaveTo: string
|
||||
}
|
||||
|
||||
export interface IClassNameProps {
|
||||
enterClass?: string
|
||||
enterActiveClass?: string
|
||||
enterToClass?: string
|
||||
leaveClass?: string
|
||||
leaveActiveClass?: string
|
||||
leaveToClass?: string
|
||||
}
|
||||
|
||||
function getDefaultClassNames(name: string) {
|
||||
return {
|
||||
enter: `${name}-enter-from`,
|
||||
enterActive: `${name}-enter-active`,
|
||||
enterTo: `${name}-enter-to ${name}-enter-active`,
|
||||
leave: `${name}-leave-from`,
|
||||
leaveActive: `${name}-leave-active`,
|
||||
leaveTo: `${name}-leave-to ${name}-leave-active`,
|
||||
}
|
||||
}
|
||||
|
||||
export function getClassNames(name: string, {
|
||||
enterClass,
|
||||
enterActiveClass,
|
||||
enterToClass,
|
||||
leaveClass,
|
||||
leaveActiveClass,
|
||||
leaveToClass,
|
||||
}: IClassNameProps): IClassNames {
|
||||
const defaultClassNames = getDefaultClassNames(name)
|
||||
return {
|
||||
enter: enterClass || defaultClassNames.enter,
|
||||
enterActive: enterActiveClass || defaultClassNames.enterActive,
|
||||
enterTo: enterToClass || defaultClassNames.enterTo,
|
||||
leave: leaveClass || defaultClassNames.leave,
|
||||
leaveActive: leaveActiveClass || defaultClassNames.leaveActive,
|
||||
leaveTo: leaveToClass || defaultClassNames.leaveTo,
|
||||
}
|
||||
}
|
||||
|
||||
export function useTransition(props: TransitionProps, emit: SetupContext<TransitionEmits>['emit']) {
|
||||
const display = ref(false)
|
||||
const name = computed(() => props.name || 'fade')
|
||||
const duration = computed(() => props.duration || 200)
|
||||
|
||||
const animationClass = ref('')
|
||||
|
||||
const classNames = computed(() =>
|
||||
getClassNames(props.name, {
|
||||
enterClass: props.enterFromClass,
|
||||
enterActiveClass: props.enterActiveClass,
|
||||
enterToClass: props.enterToClass,
|
||||
leaveClass: props.leaveFromClass,
|
||||
leaveActiveClass: props.leaveActiveClass,
|
||||
leaveToClass: props.leaveToClass,
|
||||
}),
|
||||
)
|
||||
|
||||
async function enter() {
|
||||
if (display.value)
|
||||
return
|
||||
emit('beforeEnter')
|
||||
display.value = true
|
||||
animationClass.value = defaultAnimations[name.value]?.enter ? defaultAnimations[name.value]?.enter : `${classNames.value.enter} ${classNames.value.enterActive}`
|
||||
await nextTick()
|
||||
emit('enter')
|
||||
|
||||
setTimeout(() => {
|
||||
if (!isKeyOfAnimations(props.name))
|
||||
animationClass.value = classNames.value.enterTo
|
||||
emit('afterEnter')
|
||||
}, duration.value)
|
||||
}
|
||||
|
||||
async function leave() {
|
||||
if (!display.value)
|
||||
return
|
||||
emit('beforeLeave')
|
||||
animationClass.value = defaultAnimations[name.value]?.leave ? defaultAnimations[name.value]?.leave : `${classNames.value.leave} ${classNames.value.leaveActive}`
|
||||
await nextTick()
|
||||
emit('leave')
|
||||
|
||||
setTimeout(() => {
|
||||
if (!props.show && display.value)
|
||||
display.value = false
|
||||
if (!isKeyOfAnimations(props.name))
|
||||
animationClass.value = classNames.value.leaveTo
|
||||
emit('afterLeave')
|
||||
}, duration.value)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.show,
|
||||
(val) => {
|
||||
val ? enter() : leave()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
function clickHandler(evt: any) {
|
||||
// evt.stopPropagation()
|
||||
emit(CLICK_EVENT, evt)
|
||||
}
|
||||
|
||||
const classes = computed(() => {
|
||||
return getMainClass(props, componentName, {
|
||||
[animationClass.value]: true,
|
||||
'nut-hidden': !display.value,
|
||||
})
|
||||
})
|
||||
const styles = computed(() => {
|
||||
return getMainStyle(props, {
|
||||
'animation-duration': isKeyOfAnimations(props.name) ? `${props.duration}ms` : '',
|
||||
'animation-timing-function': isKeyOfAnimations(props.name) ? props.timingFunction : '',
|
||||
})
|
||||
})
|
||||
return {
|
||||
display,
|
||||
classes,
|
||||
styles,
|
||||
clickHandler,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user