关于 vue 的 transiton 组件和 render 以及 es6 的 class 语法的问题

2020-06-13 20:40:54 +08:00
 qaqLjj

要基于 vue 实现一个 collapse 的过渡动画
当我使用 class 语法写的时候,动画的钩子函数完全没有执行
但当我使用 prototype 的形式的时候却没有这个问题
请高手指教,代码如下:
注:class 形式的构造函数为 Transition1,prototype 形式的构造函数为 Transition2

class Transition1 {
  beforeEnter(el) {
  }  
  enter(el) {
  }
  afterEnter(el) {
  }
  beforeLeave(el) {
  }
  leave(el) {
  }
  afterLeave(el) {
  }
}

function Transition2() {}
Transition2.prototype.beforeEnter = function beforeEnter(el) {}
Transition2.prototype.enter = function enter(el) {}
Transition2.prototype.afterEnter = function afterEnter(el) {}
Transition2.prototype.beforeLeave = function beforeLeave(el) {}
Transition2.prototype.leave = function leave(el) {}
Transition2.prototype.afterLeave = function afterLeave(el) {}

export default {
  functional: true,
  render(h, { children }) {
    const data = {
      on: new Transition1()
    }
    return h('transition', data, children)
  }
}

为了方便阅读,这些钩子函数的具体内容我省略掉了
实在令人疑惑,class 应该只是个语法糖啊,为什么会有不一样的表现

784 次点击
所在节点    问与答
5 条回复
noe132
2020-06-13 21:37:16 +08:00
因为你的 prototype 没有正确的模拟 class 的行为。

> Reflect.getOwnPropertyDescriptor(Transition1.prototype, 'beforeEnter').enumerable
< false
> Reflect.getOwnPropertyDescriptor(Transition2.prototype, 'beforeEnter').enumerable
< true

而 vue 在初始化 transition 的选项时用到了 extend 函数,里面使用 for...in 遍历属性。for...in 遍历的时 enumrable non symbol property.

https://github.com/vuejs/vue/blob/4de4649d9637262a9b007720b59f80ac72a5620c/src/shared/util.js#L231

而且通常这种东西不会用 class 来实现。普通对象不就够了么?
noe132
2020-06-13 21:39:13 +08:00
把 class 放到 babel compile 一下 https://babeljs.io/repl
你就知道区别了
qaqLjj
2020-06-13 22:24:53 +08:00
@noe132 非常感谢你的回答,终于知道问题出在哪里了。
除了这个问题我还有两个问题能否指教一下 ,我文中贴的代码结构基本和 element-ui 的 el-collapse-transition 组件相同
1.如你所说,这里 element-ui 源码中为什么不直接 const 声明一个变量。
2.为什么 element-ui 源码中可以使用 class 语法,源码用了什么库转译了 class 并且不影响使用
https://github.com/ElemeFE/element/blob/dev/src/transitions/collapse-transition.js
noe132
2020-06-13 23:19:25 +08:00
element-ui 很可能用了老版本的 babel
https://unpkg.com/element-ui@2.13.2/lib/transitions/collapse-transition.js
编译出来的代码是不符合 class 正确语义的
qaqLjj
2020-06-13 23:40:15 +08:00
@noe132 是的,对象原型上的方法可以枚举是不符合 es6 规范的,再次感谢你的帮助
https://w3ctech.com/topic/1708

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/681316

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX