transition-group组件v-move的实现原理(个人理解)

transition-group组件v-move实现原理的一些理解
  • 在查看到官方文档的transition-group的时候,发现transition-group组件可以使得整个transition-group里的li(或其他元素)都能够准确的移动到他们的正确的位置,并在此期间添加上动画。特别是就算你移除\添加节点也有动画
  • 我们知道,在dom里删除\添加节点时,浏览器是直接重绘的,哪里还会给你整个动画?
  • 所以我关注的其实就是,vue移除\添加节点时是怎么实现添加动画的

在查看源码后,发现了一点线索,现在整理出来,也算是解决了自己的一点小疑惑。(或许?)

以下属于个人理解,如有错误,欢迎批评指正

< transition-group >源码地址
https://github.com/vuejs/vue/blob/dev/src/platforms/web/runtime/components/transition-group.js

1、实现思路解析:
  • 1、在render()函数中,发现下面几行代码,不拿发现每次render都会获取到每个li(或者其他元素,这里用li做代表)所对应的的位置(或其他数据)并储存在各自的c.data.pos中(c代表这个vnode)
render(){
	...
	//const c = this.$slots.default || []
	//第83行
	c.data.pos = c.elm.getBoundingClientRect()
	...
}
  • 2、接下来,在updated()生命周期函数里,通过children.forEach(recordPosition)来记录我们每个节点的新的位置,并储存在c.data.newPos中(c代表这个vnode)
updated(){
	...
	//第107行
	children.forEach(recordPosition)
	...
	//第175行
	function recordPosition (c: VNode) {
	  c.data.newPos = c.elm.getBoundingClientRect()
	}
}
  • 3、通过css属性实现从c.data.posc.data.newPos的过渡动画,就实现了transition-group动画,
//第108行
children.forEach(applyTranslation)
//第179行
function applyTranslation (c: VNode) {
  const oldPos = c.data.pos
  const newPos = c.data.newPos
  const dx = oldPos.left - newPos.left
  const dy = oldPos.top - newPos.top
  if (dx || dy) {
    c.data.moved = true
    const s = c.elm.style
    s.transform = s.WebkitTransform = `translate(${dx}px,${dy}px)`
    s.transitionDuration = '0s'
  }
}
2、回到我的疑问点

如果在新的页面里,添加或删除了某个节点呢?

  • 添加节点时时:
    • 由于是新添加的,所以没有c.data.pos(初始的css数据),那么就把v-enter的值赋给c.data.pos。既然是个新添加的节点并出现在了页面上,那肯定有c.data.newPos嘛。
    • 这样,有了c.data.posc.data.newPos,就能在添加节点时实现动画了!
  • 删除节点时:
    • 由于移除,所以没有了c.data.newPos数据,那么把v-leave-to的值赋给c.data.newPos
    • 同上,有了c.data.posc.data.newPos,就能在删除节点时实现动画了!
//c.data.moved 是在updated()中计算并保存的需要移除的节点数组
//第115行
 children.forEach((c: VNode) => {
      if (c.data.moved) {
        //相关操作
      }
    })
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值