Skip to content

Transition 过渡动画 ​

17:06

说明 ​

进出场过渡封装:以 CSS transition + 类切换驱动内容显隐(uni-app x App 端不支持 @keyframes,故不依赖它),内置 fade / slide-* / zoom-* 七种预设,duration / timing-function / delay 可调。动画完成按 duration + delay 的定时器判定(App 端 transitionend 可能不触发),因此 after-enter / after-leave 在设定时长后触发。

兼容性 ​

平台支持情况
App✅ 支持(动画走 CSS transition + 类切换,不使用 @keyframes;完成判定用时长定时器,不依赖 transitionend)
H5✅ 支持
微信小程序✅ 支持

示例 ​

基础用法 ​

show 控制内容显隐,默认 fade 淡入淡出;组件只负责过渡,内容高度由用户自定。

查看源码
vue
<template>
    <ux-transition :show="show" name="fade" :duration="300">
        <view class="card">
            <text>过渡内容</text>
        </view>
    </ux-transition>
    <ux-button text="切换显示" type="primary" shape="round" @click="show = !show" />
</template>

<script setup lang="uts">
const show = ref(true);
</script>

预设动画 name ​

支持 fade / slide-up / slide-down / slide-left / slide-right / zoom-in / zoom-out 七种预设,点击切换并立即重播。

查看源码
vue
<template>
    <!-- name 可选 fade / slide-up / slide-down / slide-left / slide-right / zoom-in / zoom-out -->
    <ux-transition :show="show" :name="current" :duration="300">
        <view class="card">
            <text>过渡内容</text>
        </view>
    </ux-transition>
    <ux-button text="重播动画" type="primary" shape="round" @click="replay" />
</template>

<script setup lang="uts">
const show = ref(true);
const current = ref('slide-up');

// 离场过渡结束后再进场,完成一次重播
const replay = () => {
    show.value = false;
    setTimeout(() => {
        show.value = true;
    }, 450);
};
</script>

动画时长 duration ​

duration 设置进入与离开的过渡时长,单位毫秒。

查看源码
vue
<template>
    <ux-transition :show="show" name="slide-up" :duration="duration">
        <view class="card">
            <text>过渡内容</text>
        </view>
    </ux-transition>
    <ux-button text="重播动画" type="primary" shape="round" @click="replay" />
</template>

<script setup lang="uts">
const show = ref(true);
const duration = ref(300);

const replay = () => {
    show.value = false;
    setTimeout(() => {
        show.value = true;
    }, duration.value + 150);
};
</script>

动画曲线 timing-function ​

timing-function 自定义缓动曲线,回弹曲线让动画更有弹性。

查看源码
vue
<template>
    <ux-transition :show="show" name="zoom-in" :duration="500" :timing-function="timingFunction">
        <view class="card">
            <text>过渡内容</text>
        </view>
    </ux-transition>
</template>

<script setup lang="uts">
const show = ref(true);
// 默认曲线(标准);回弹曲线可取 cubic-bezier(0.175, 0.885, 0.32, 1.275)
const timingFunction = ref('cubic-bezier(0.2, 0.8, 0.2, 1)');
</script>

动画延迟 delay ​

delay 设置过渡启动前的延迟,进入与离开都生效,完成事件在时长+延迟后触发。

查看源码
vue
<template>
    <view class="row">
        <text>延迟 (ms)</text>
        <ux-number-box v-model="delay" :step="100" :min="0" :max="600" />
    </view>
    <ux-transition :show="show" name="slide-left" :duration="300" :delay="delay">
        <view class="card">
            <text>过渡内容</text>
        </view>
    </ux-transition>
</template>

<script setup lang="uts">
const show = ref(true);
const delay = ref(0);
</script>

首次渲染动画 appear ​

appear=true 时组件首次挂载即播放进场动画;需重新挂载才能复现(外层 v-if 重建)。

查看源码
vue
<template>
    <view class="row">
        <text>首次渲染播放进场动画</text>
        <ux-switch v-model="appear" />
    </view>
    <!-- 外层 v-if 重挂:appear 只在组件首次挂载时生效,重新挂载才能复现 -->
    <view v-if="mounted">
        <ux-transition :show="true" name="zoom-out" :duration="500" :appear="appear">
            <view class="card">
                <text>过渡内容</text>
            </view>
        </ux-transition>
    </view>
    <ux-button text="重新挂载" type="primary" shape="round" @click="remount" />
</template>

<script setup lang="uts">
const appear = ref(true);
const mounted = ref(true);

const remount = () => {
    mounted.value = false;
    setTimeout(() => {
        mounted.value = true;
    }, 50);
};
</script>

事件回调 ​

监听进出场全生命周期:before-enter / enter / after-enter / enter-cancelled / before-leave / leave / after-leave / leave-cancelled。

查看源码
vue
<template>
    <ux-transition
        :show="show"
        name="slide-up"
        :duration="400"
        @before-enter="logEvent('before-enter')"
        @enter="logEvent('enter')"
        @after-enter="logEvent('after-enter')"
        @enter-cancelled="logEvent('enter-cancelled')"
        @before-leave="logEvent('before-leave')"
        @leave="logEvent('leave')"
        @after-leave="logEvent('after-leave')"
        @leave-cancelled="logEvent('leave-cancelled')"
    >
        <view class="card">
            <text>过渡内容</text>
        </view>
    </ux-transition>
    <ux-button text="切换显示" type="primary" shape="round" @click="show = !show" />
    <view class="log">
        <text v-for="(item, index) in logs" :key="index">{{ item }}</text>
    </view>
</template>

<script setup lang="uts">
const show = ref(true);
const logs = ref<string[]>([]);

const logEvent = (name: string) => {
    logs.value = ([name] as string[]).concat(logs.value.slice(0, 7));
};
</script>

自定义样式 custom-class / custom-style ​

custom-class 扩展根节点样式类,custom-style 内联自定义样式。

查看源码
vue
<template>
    <ux-transition
        custom-class="my-transition"
        :custom-style="customStyle"
        :show="show"
        name="fade"
        :duration="400"
    >
        <view class="card">
            <text>过渡内容</text>
        </view>
    </ux-transition>
</template>

<script setup lang="uts">
const show = ref(true);
const customStyle = ref<UTSJSONObject>({
    'background-color': '#edf4ff',
    'border-radius': '8px'
});
</script>

<style scoped>
/* custom-class 外部类:为过渡根节点补充内边距 */
.my-transition {
    padding: 12px;
}
</style>

API ​

Props ​

属性说明类型默认值版本
customStyle自定义根节点样式UTSJSONObject--
customClass自定义根节点样式类string''-
show是否展示(默认true)Booleantrue-
name预设动画:fade/slide-up/slide-down/slide-left/slide-right/zoom-in/zoom-out(默认fade)String'fade'-
duration进入/离开动画时长,单位ms(默认300)Number300-
timingFunction动画曲线(默认cubic-bezier(0.2,0.8,0.2,1))String'cubic-bezier(0.2, 0.8, 0.2, 1)'-
delay动画延迟,单位ms,进入与离开都生效(默认0)Number0-
appear首次渲染时是否播放进场动画(默认false)Booleanfalse-

Events ​

事件名说明回调参数版本
before-enter开始进入--
enter进入动画真正启动(挂载隔一拍切终态类后;重开场景与 before-enter 同拍)--
after-enter进入动画结束--
enter-cancelled进入动画未完成即被离开打断--
before-leave开始离开--
leave离开动画启动(与 before-leave 同拍,预留)--
after-leave离开动画结束(DOM 已卸载)--
leave-cancelled离开动画未完成即被重进打断--

Slots ​

插槽名说明版本
default过渡的内容(显隐时整体做进出场过渡)-

注意事项 ​

  • appear 只在组件首次挂载时生效,之后切换 show 不再播放进场动画;要复现需重建组件(外层 v-if)。
  • 完成事件(after-enter / after-leave)由 duration + delay 的定时器判定,不依赖 transitionend(App 端可能不触发),与实际渲染帧可能有一拍偏差。
  • leave 播完才卸载 DOM;进场途中切离场会派发 enter-cancelled,离场途中重开会派发 leave-cancelled。
  • 未知的 name 会回退为 fade。
  • App 端 transition-duration / transition-delay 不支持多值列表,故时长 / 延迟 / 曲线按单值内联下发,起始与终态属性由预设类提供。