V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
qaqLjj
V2EX  ›  问与答

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

  •  
  •   qaqLjj · 2020-06-13 20:40:54 +08:00 · 777 次点击
    这是一个创建于 1384 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要基于 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 应该只是个语法糖啊,为什么会有不一样的表现

    5 条回复    2020-06-13 23:40:15 +08:00
    noe132
        1
    noe132  
       2020-06-13 21:37:16 +08:00   ❤️ 1
    因为你的 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
        2
    noe132  
       2020-06-13 21:39:13 +08:00
    把 class 放到 babel compile 一下 https://babeljs.io/repl
    你就知道区别了
    qaqLjj
        3
    qaqLjj  
    OP
       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
        4
    noe132  
       2020-06-13 23:19:25 +08:00
    element-ui 很可能用了老版本的 babel
    https://unpkg.com/[email protected]/lib/transitions/collapse-transition.js
    编译出来的代码是不符合 class 正确语义的
    qaqLjj
        5
    qaqLjj  
    OP
       2020-06-13 23:40:15 +08:00
    @noe132 是的,对象原型上的方法可以枚举是不符合 es6 规范的,再次感谢你的帮助
    https://w3ctech.com/topic/1708
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5308 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 09:10 · PVG 17:10 · LAX 02:10 · JFK 05:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.