27

其实,如何在特定框架里使用一款并非为该框架定制的库/插件,只有两点:
1.熟悉这个框架
2.熟悉这个库/插件的工作原理

说完废话。进入正题。
perfect-scrollbar是一款轻量级的滚动插件,具体介绍详见其官网
你只需要知道它绝对不是为了vue设计的,和vue没半毛钱关系。那么如何完美的融合其中呢?

以下是我的步骤
首先,安装包

npm install perfect-scrollbar --save

其次,引入包。为了能够在项目中信手拈来的使用而不是每个要用的组件都去引入一遍,我们应该在主入口引入并注册为自定义指令。

//main.js

//引入核心框架
import Vue from 'vue';
//插件的包
import PerfectScrollbar from 'perfect-scrollbar';
//对应的css
import "perfect-scrollbar/css/perfect-scrollbar.css";

/**
 * @description 自动判断该更新PerfectScrollbar还是创建它
 * @param {HTMLElement} el - 必填。dom元素
 */
const el_scrollBar = (el) => {
    //在元素上加点私货,名字随便取,确保不会和已有属性重复即可,我取名叫做_ps_
    if (el._ps_ instanceof PerfectScrollbar) {
        el._ps_.update();
    } else {
        //el上挂一份属性
        el._ps_ = new PerfectScrollbar(el, {
            // 要配什么属性自己看官网,此处不会解释任何其配置项的含义
            suppressScrollX: true,
        });
    }
};

//接着,自定义Vue指令,指令名你自己随便编一个,我们假定它叫scrollBar
Vue.directive("scrollBar", {
    //使用inserted钩子函数(初次创建dom)获取使用自定义指令处的dom
    inserted(el, binding, vnode) {
        //判断其样式是否存在position 并且position为"fixed", "absolute"或"relative"
        //如果不符合条件,抛个错误。当然你也可以抛个警告然顺便给其position自动加上"relative"
        //为什么要这么做呢,因为PerfectScrollbar实现原理就是对dom注入两个div,一个是x轴一个是y轴,他们两的position都是absolute。
        //对css稍有常识的人都知道,absolute是相对于所有父节点里设置了position属性的最近的一个节点来定位的,为了能够正确定位,我们要给其设置position属性
        const rules = ["fixed", "absolute", "relative", "sticky"];
        if (!rules.includes(window.getComputedStyle(el, null).position)) {
            console.error(`perfect-scrollbar所在的容器的position属性必须是以下之一:${rules.join("、")}`)
        }
        //el上挂一份属性
        el_scrollBar(el);
    },
    //更新dom的时候
    componentUpdated(el, binding, vnode, oldVnode) {
        //vnode.context其实就是vue实例,这里其实无需实例也直接用Vue的静态方法
        //故而也可以写成Vue.nextTick
        vnode.context.$nextTick(
            () => {
                el_scrollBar(el);
            }
        )
    }
})

至此,我们完成了PerfectScrollbar在vue的准备工作
接下来我们试试如何调用。
用法相当简单,在要用到的地方直接写一个v-scrollBar

//具体组件

<template>
    <div class="container">
        <ul class="list" v-scrollBar>
           <li>巴拉巴拉</li>
           <li>炫光舞法</li>
           <!--想象这里有一堆li-->
           <li>天舞台</li>
        </ul>
    </div>
</template>

<style lang="less" scoped>
.list{
    position:relative;
    /*不写高度说明高度自适应,既然高度都无限了根本就不会出现滚动条*/
    height:300px;
}
</style>

是不是很简单,只要在要用到滚动条的那个ul上面加一个v-scrollBar即可,其余什么都不用操心。

最后,还要注意一下兼容性
perfect-scrollbar官网描述。它对ie的支持仅完美支持ie11,然后ie10勉强能用
那么vue是支持到ie9的。我们至少要让他在ie9上能用

那么现在的这个状态直接在ie9上试试。应该会得到一个类似于
Uncaught TypeError: Cannot read property 'add' of undefined
的报错。

那么我们打开perfect-scrollbar的源码看看

clipboard.png

有.add的地方就这两处 都是classList的方法
那么classList是什么,参见mdn
ie9上没有对其实现,所以我们挂一个对其的垫片
再来安装一个包

npm install classlist-polyfill --save

然后在引入perfect-scrollbar包之前(其实在它被实例化之前就行)引入它

//main.js 头部引包部分改一下

//引入核心框架
import Vue from 'vue';
//classList的垫片
import "classlist-polyfill";
//插件的包
import PerfectScrollbar from 'perfect-scrollbar';
//对应的css
import "perfect-scrollbar/css/perfect-scrollbar.css";

至此大功告成


阿蛇
3k 声望224 粉丝