Vue源码解析之transition(二)

641 阅读3分钟

上一篇介绍了transition组件,但是并没有触及transition的核心:控制过渡效果,这篇文章将分析控制原理。

hooks

transition组件只有在浏览器环境下才会起作用,在组件patch的过程中会调用一系列的钩子。这里在create/active/remove钩子上设置了回调函数。

create/activate会执行enter函数,remove执行leave函数。

_enter及enter

第一部分

这里也将enter函数分为三个部分,第一部分主要还是做一些条件判断

1. 在leave函数中会定义leaveCb,如果有就执行回调

2. 解析vnode.data.taransition,这里主要是为各种Class添加名称

3. el._enterCb为后面enter函数定义的,假设enterCb仍未执行或者改节点不是元素节点就return

4. 获取解析后的data内各种属性,包裹过渡类名及回调函数(对于mode,定义了默认的一些回调函数)。

5. 取isAppear值,同transition的hasParentTransition一样,探索边界条件,在transition组件是组件根节点的情况下,需要继续向上探索祖先组件。当祖先组件没有挂载且

6. appear为用户绑定的属性,默认为false,直接return;如果为ture就表示首次渲染的时候也要执行过渡动画。

第二部分

1. 解析类名,回调函数

2. expectCSS:是否使用css来控制过渡动画;userWantedControl:是否用户自己来控制过渡

3. 定义回调函数_enterCb在下面四种情况下会执行:

1.非用户控制过渡:transition/animation事件完成后执行回调;
2.非用户控制过渡:在定义的延迟时机后执行回调
3\. 节点移除的时候如果el._enterCb!==null 执行回调
4\. 与v-show有关,data.show为false/undefined时,在节点insert的时候执行回调
5\. v-show为true的时候立刻执行回调

上述第四条情况的细节:

4. 开始执行动画

1. 首先执行beforeEnter钩子

2. 添加startClass,activeClass(组件的create钩子执行)

3.nextFrame利用raf来控制过渡,下一帧的时候去除startClass

4.去除startClass的同时添加toClass

5.如果不是用户控制动画就在1)如果设置了延迟之间就在延迟时间之后调用;2)否则就在过渡效果结束后调用

5. v-show为true的直接调用enterHook

关于enterCb用once包裹的原因:

当vnode没有v-show属性或者v-show为false的时候,肯定会添加insertHook,insertHook在节点被插入的时候执行对应回调。该回调会调用_enterCb。这会导致同时满足好几种可以执行的情况,因此enterCb用once函数包裹了一层,确保过渡效果值只执行一次。

关于钩子函数执行的顺序:

beforeEnterHook在组件create/actived触发;enterHook在v-show为false/没有定义v-show的时候,在组件insert在触发,insert肯定在create后面;至于v-show为true,enterHook同步在beforeEnterHook后调用

leave

在组件remove的时候会调用leave函数。

其实leave和enter几乎是一样的,因此不做过多分析。

leaveClass对应startClass, leaveActiveClass对应activeClass,leaveToClass对应toClass。

_leaveCb的定义及调用时机也与_enterCb类似。beforeLeave对应beforeEnter。

关于cb.cancelled

有可能出现enter没有执行完就执行leave的情况下,因此通过_enterCb/_leaveCb是否为null及cancelled来表明这个情况,并做相应的处理。

最后

transition组件只是对props与几个回调函数做了处理,将其绑定在真实子元素上。

在patch过程中会触发create/activate/insert/remove钩子,这些hook存储了了用户及组件定义的钩子函数,当组件钩子触发的时候,定义的回调函数也被触发了。

由这些回调函数通过给元素在不同时期添加/删除不同的class,通过css来添加过渡效果。

此外,在组件的css属性为false的时候时候,用户可以通过一系列的用户定义的钩子函数(enterHook,beforeEnterHook等)来控制js动画效果。