el-collapse-transition 移植到项目中遇到的问题,及其解决方法。

16 篇文章 0 订阅
7 篇文章 0 订阅

el-collapse-transition 移植到项目中遇到的问题,及其解决方法

问题描述

 自有项目中需要实现一个collapse折叠面板的功能,由于对饿了么使用较多,故打算将饿了么中的collapse组件移植到项目中,只需要对一些细节的样式进行修改即可。本着兢(混)兢(水)业(摸)业(鱼)的态度,开始移植collapse折叠面板。
 但是在查看饿了么的源码,以及实现了collapse功能后,发现面板的动画效果失效了,打开折叠的操作感觉很生硬。影响使用体验。
 经过细致的排查,发现问题出现在 el-collapse-transition 组件上,通过断点发现,改组件的render有加载,但是class Transition完全不会被呼叫,即class Transition里定义的各种方法没有被触发,所以导致el-collapse-transition 失效。

思路解析

 问题出现在 el-collapse-transition 组件上,但是移植时代码已饿了么的源码一致,实现方式是通过vue的函数式组件的方式来实现的,对于函数式组件也不是很了解。多方查找原因,发现出在这个原来是ES6中class类的原型是不可以在vue中通过v-for遍历的。可以将ES6的class类的写法换成ES5的写法,ES5中class类的原型是可以进行遍历的。
  new 出来的实例 的各种方法 是挂在新对象的原型上, 但是on 里面的函数必须是要在新对象本身上。
  本着这个想法,看了饿了么npm包中transition文件夹下collapse-transition.js文件,果然写法转换为了ES5的写法。应该是饿了么发布npm时通过babel转换了写法。

解决方案

方法一

简单一些,可以直接将elementUI的npm包中的源码直接拿过来,可以正常运行,也不需要自己在进行其他的改写。
注意的一点是对dom.js的引入,文件位置的变化。
附上饿了么转译后的代码:

'use strict';

exports.__esModule = true;

var _dom = require('element-ui/lib/utils/dom');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Transition = function () {
  function Transition() {
    _classCallCheck(this, Transition);
  }

  Transition.prototype.beforeEnter = function beforeEnter(el) {
    (0, _dom.addClass)(el, 'collapse-transition');
    if (!el.dataset) el.dataset = {};

    el.dataset.oldPaddingTop = el.style.paddingTop;
    el.dataset.oldPaddingBottom = el.style.paddingBottom;

    el.style.height = '0';
    el.style.paddingTop = 0;
    el.style.paddingBottom = 0;
  };

  Transition.prototype.enter = function enter(el) {
    el.dataset.oldOverflow = el.style.overflow;
    if (el.scrollHeight !== 0) {
      el.style.height = el.scrollHeight + 'px';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    } else {
      el.style.height = '';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    }

    el.style.overflow = 'hidden';
  };

  Transition.prototype.afterEnter = function afterEnter(el) {
    (0, _dom.removeClass)(el, 'collapse-transition');
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
  };

  Transition.prototype.beforeLeave = function beforeLeave(el) {
    if (!el.dataset) el.dataset = {};
    el.dataset.oldPaddingTop = el.style.paddingTop;
    el.dataset.oldPaddingBottom = el.style.paddingBottom;
    el.dataset.oldOverflow = el.style.overflow;

    el.style.height = el.scrollHeight + 'px';
    el.style.overflow = 'hidden';
  };

  Transition.prototype.leave = function leave(el) {
    if (el.scrollHeight !== 0) {
      (0, _dom.addClass)(el, 'collapse-transition');
      el.style.height = 0;
      el.style.paddingTop = 0;
      el.style.paddingBottom = 0;
    }
  };

  Transition.prototype.afterLeave = function afterLeave(el) {
    (0, _dom.removeClass)(el, 'collapse-transition');
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
    el.style.paddingTop = el.dataset.oldPaddingTop;
    el.style.paddingBottom = el.dataset.oldPaddingBottom;
  };

  return Transition;
}();

exports.default = {
  name: 'ElCollapseTransition',
  functional: true,
  render: function render(h, _ref) {
    var children = _ref.children;

    var data = {
      on: new Transition()
    };

    return h('transition', data, children);
  }
};

方法二:

需要一定的ES5中class类的实现基础,将原来饿了么源码中的ES6写法仔细改写为ES5的class类实现,限于本人水平有限,放弃了这种方式o(╥﹏╥)o

方法三:

此方法无需改写成ES5写法,需要将transition定义为一个对象(变量),即将:

class Transition {
	beforeEnter(el) { ...}
	enter(el) { ...}
	....
}

改写为:

const Transition = {
	beforeEnter(el) { ...},
	enter(el) { ...},
	....
}

然后在render中将

 render: function render(h, _ref) {
    var children = _ref.children;

    var data = {
      on: new Transition()
    };

    return h('transition', data, children);
  }

修改为:

 render: function render(h, _ref) {
    var children = _ref.children;

    var data = {
      on:  Transition
    };

    return h('transition', data, children);
  }

但是这样写的话,肯定是有问题的, 所有生成的组件都共用了一个对象。当使用较多改组件时,由于共用一个对象,会变得难以维护。
以上即为关于el-collapse-transition移植遇到问题的解决方法。

 tips:
    点滴记录,汇聚江河

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值