| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 | // 定义一个一定时间后自动成功的promise,让调用nextTick方法处,进入下一个then方法const nextTick = () => new Promise(resolve => setTimeout(resolve, 1000 / 50))// nvue动画模块实现细节抽离在外部文件import animationMap from './nvue.ani-map.js'// #ifndef APP-NVUE// 定义类名,通过给元素动态切换类名,赋予元素一定的css动画样式const getClassNames = (name) => ({    enter: `u-${name}-enter u-${name}-enter-active`,    'enter-to': `u-${name}-enter-to u-${name}-enter-active`,    leave: `u-${name}-leave u-${name}-leave-active`,    'leave-to': `u-${name}-leave-to u-${name}-leave-active`})// #endif// #ifdef APP-NVUE// 引入nvue(weex)的animation动画模块,文档见:// https://weex.apache.org/zh/docs/modules/animation.html#transitionconst animation = uni.requireNativePlugin('animation')const getStyle = (name) => animationMap[name]// #endifexport default {    methods: {        // 组件被点击发出事件        clickHandler() {            this.$emit('click')        },        // #ifndef APP-NVUE        // vue版本的组件进场处理         vueEnter() {            // 动画进入时的类名            const classNames = getClassNames(this.mode)            // 定义状态和发出动画进入前事件            this.status = 'enter'            this.$emit('beforeEnter')            this.inited = true            this.display = true            this.classes = classNames.enter            this.$nextTick(async () => {				// #ifdef H5				await uni.$u.sleep(20)				// #endif                // 标识动画尚未结束                this.$emit('enter')                this.transitionEnded = false				// 组件动画进入后触发的事件                this.$emit('afterEnter')                // 赋予组件enter-to类名                this.classes = classNames['enter-to']            })        },        // 动画离场处理        vueLeave() {            // 如果不是展示状态,无需执行逻辑            if (!this.display) return            const classNames = getClassNames(this.mode)            // 标记离开状态和发出事件            this.status = 'leave'            this.$emit('beforeLeave')            // 获得类名            this.classes = classNames.leave            this.$nextTick(() => {               // 动画正在离场的状态               this.transitionEnded = false               this.$emit('leave')                // 组件执行动画,到了执行的执行时间后,执行一些额外处理                setTimeout(this.onTransitionEnd, this.duration)                this.classes = classNames['leave-to']            })        },        // #endif        // #ifdef APP-NVUE        // nvue版本动画进场        nvueEnter() {            // 获得样式的名称            const currentStyle = getStyle(this.mode)            // 组件动画状态和发出事件            this.status = 'enter'            this.$emit('beforeEnter')            // 展示生成组件元素            this.inited = true            this.display = true            // 在nvue安卓上,由于渲染速度慢,在弹窗,键盘,日历等组件中,渲染其中的内容需要时间            // 导致出现弹窗卡顿,这里让其一开始为透明状态,等一定时间渲染完成后,再让其隐藏起来,再让其按正常逻辑出现            this.viewStyle = {                opacity: 0            }            // 等待弹窗内容渲染完成            this.$nextTick(() => {                // 合并样式                this.viewStyle = currentStyle.enter                Promise.resolve()                    .then(nextTick)                    .then(() => {                        // 组件开始进入前的事件                        this.$emit('enter')                        // nvue的transition动画模块需要通过ref调用组件,注意此处的ref不同于vue的this.$refs['u-transition']用法                        animation.transition(this.$refs['u-transition'].ref, {                            styles: currentStyle['enter-to'],                            duration: this.duration,                            timingFunction: this.timingFunction,                            needLayout: false,                            delay: 0                        }, () => {                            // 动画执行完毕,发出事件                            this.$emit('afterEnter')                        })                    })                    .catch(() => {})            })        },        nvueLeave() {            if (!this.display) {                return            }            const currentStyle = getStyle(this.mode)            // 定义状态和事件            this.status = 'leave'            this.$emit('beforeLeave')            // 合并样式            this.viewStyle = currentStyle.leave            // 放到promise中处理执行过程            Promise.resolve()                .then(nextTick) // 等待几十ms                .then(() => {                    this.transitionEnded = false                    // 动画正在离场的状态                    this.$emit('leave')                    animation.transition(this.$refs['u-transition'].ref, {                        styles: currentStyle['leave-to'],                        duration: this.duration,                        timingFunction: this.timingFunction,                        needLayout: false,                        delay: 0                    }, () => {                        this.onTransitionEnd()                    })                })                .catch(() => {})        },        // #endif        // 完成过渡后触发        onTransitionEnd() {            // 如果已经是结束的状态,无需再处理            if (this.transitionEnded) return            this.transitionEnded = true            // 发出组件动画执行后的事件            this.$emit(this.status === 'leave' ? 'afterLeave' : 'afterEnter')            if (!this.show && this.display) {                this.display = false                this.inited = false            }        }    }}
 |