// 定义一个一定时间后自动成功的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#transition 
 | 
const animation = uni.requireNativePlugin('animation') 
 | 
const getStyle = (name) => animationMap[name] 
 | 
// #endif 
 | 
  
 | 
export 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 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
} 
 |