123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- <template>
- <view
- v-if="inited"
- class="u-transition"
- ref="u-transition"
- @tap="clickHandler"
- :class="classes"
- :style="[mergeStyle]"
- @touchmove="noop"
- >
- <slot />
- </view>
- </template>
- <script>
- import { props } from './props';
- import { mpMixin } from '../../libs/mixin/mpMixin';
- import { mixin } from '../../libs/mixin/mixin';
- import { addStyle } from '../../libs/function/index';
- // 组件的methods方法,由于内容较长,写在外部文件中通过mixin引入
- import transitionMixin from "./transitionMixin.js";
- /**
- * transition 动画组件
- * @description
- * @tutorial
- * @property {String} show 是否展示组件 (默认 false )
- * @property {String} mode 使用的动画模式 (默认 'fade' )
- * @property {String | Number} duration 动画的执行时间,单位ms (默认 '300' )
- * @property {String} timingFunction 使用的动画过渡函数 (默认 'ease-out' )
- * @property {Object} customStyle 自定义样式
- * @event {Function} before-enter 进入前触发
- * @event {Function} enter 进入中触发
- * @event {Function} after-enter 进入后触发
- * @event {Function} before-leave 离开前触发
- * @event {Function} leave 离开中触发
- * @event {Function} after-leave 离开后触发
- * @example
- */
- export default {
- name: 'u-transition',
- data() {
- return {
- inited: false, // 是否显示/隐藏组件
- viewStyle: {}, // 组件内部的样式
- status: '', // 记录组件动画的状态
- transitionEnded: false, // 组件是否结束的标记
- display: false, // 组件是否展示
- classes: '', // 应用的类名
- }
- },
- emits: ['click', 'beforeEnter', 'enter', 'afterEnter', 'beforeLeave', 'leave', 'afterLeave'],
- computed: {
- mergeStyle() {
- const { viewStyle, customStyle } = this
- return {
- // #ifndef APP-NVUE
- transitionDuration: `${this.duration}ms`,
- // display: `${this.display ? '' : 'none'}`,
- transitionTimingFunction: this.timingFunction,
- // #endif
- // 避免自定义样式影响到动画属性,所以写在viewStyle前面
- ...addStyle(customStyle),
- ...viewStyle
- }
- }
- },
- // 将mixin挂在到组件中,实际上为一个vue格式对象。
- mixins: [mpMixin, mixin, transitionMixin, props],
- watch: {
- show: {
- handler(newVal) {
- // vue和nvue分别执行不同的方法
- // #ifdef APP-NVUE
- newVal ? this.nvueEnter() : this.nvueLeave()
- // #endif
- // #ifndef APP-NVUE
- newVal ? this.vueEnter() : this.vueLeave()
- // #endif
- },
- // 表示同时监听初始化时的props的show的意思
- immediate: true
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- /* #ifndef APP-NVUE */
- // vue版本动画相关的样式抽离在外部文件
- // @use './vue.ani-style.scss' as *;
- /**
- * vue版本动画内置的动画模式有如下:
- * fade:淡入
- * zoom:缩放
- * fade-zoom:缩放淡入
- * fade-up:上滑淡入
- * fade-down:下滑淡入
- * fade-left:左滑淡入
- * fade-right:右滑淡入
- * slide-up:上滑进入
- * slide-down:下滑进入
- * slide-left:左滑进入
- * slide-right:右滑进入
- */
- $u-zoom-scale: scale(0.95);
- .u-fade-enter-active,
- .u-fade-leave-active {
- transition-property: opacity;
- }
- .u-fade-enter,
- .u-fade-leave-to {
- opacity: 0
- }
- .u-fade-zoom-enter,
- .u-fade-zoom-leave-to {
- transform: $u-zoom-scale;
- opacity: 0;
- }
- .u-fade-zoom-enter-active,
- .u-fade-zoom-leave-active {
- transition-property: transform, opacity;
- }
- .u-fade-down-enter-active,
- .u-fade-down-leave-active,
- .u-fade-left-enter-active,
- .u-fade-left-leave-active,
- .u-fade-right-enter-active,
- .u-fade-right-leave-active,
- .u-fade-up-enter-active,
- .u-fade-up-leave-active {
- transition-property: opacity, transform;
- }
- .u-fade-up-enter,
- .u-fade-up-leave-to {
- transform: translate3d(0, 100%, 0);
- opacity: 0
- }
- .u-fade-down-enter,
- .u-fade-down-leave-to {
- transform: translate3d(0, -100%, 0);
- opacity: 0
- }
- .u-fade-left-enter,
- .u-fade-left-leave-to {
- transform: translate3d(-100%, 0, 0);
- opacity: 0
- }
- .u-fade-right-enter,
- .u-fade-right-leave-to {
- transform: translate3d(100%, 0, 0);
- opacity: 0
- }
- .u-slide-down-enter-active,
- .u-slide-down-leave-active,
- .u-slide-left-enter-active,
- .u-slide-left-leave-active,
- .u-slide-right-enter-active,
- .u-slide-right-leave-active,
- .u-slide-up-enter-active,
- .u-slide-up-leave-active {
- transition-property: transform;
- }
- .u-slide-up-enter,
- .u-slide-up-leave-to {
- transform: translate3d(0, 100%, 0)
- }
- .u-slide-down-enter,
- .u-slide-down-leave-to {
- transform: translate3d(0, -100%, 0)
- }
- .u-slide-left-enter,
- .u-slide-left-leave-to {
- transform: translate3d(-100%, 0, 0)
- }
- .u-slide-right-enter,
- .u-slide-right-leave-to {
- transform: translate3d(100%, 0, 0)
- }
- .u-zoom-enter-active,
- .u-zoom-leave-active {
- transition-property: transform
- }
- .u-zoom-enter,
- .u-zoom-leave-to {
- transform: $u-zoom-scale
- }
- /* #endif */
- .u-transition {}
- </style>
|