前言
本文所列封装组件的步骤,是以 Element UI 的回到顶部组件为例,但不完全局限于它(至少可以做个参考)。所展示的 demo 也做了一点修改。
封装步骤
以下回答仅是个人对 vue 组件封装的一些见解,不一定全对,若有不妥之处,还请谅解。
1. 明确将要封装的组件是装饰性的组件还是功能性的组件?
这个问题很好理解,说白了就是你将要封装的组件是用来做啥的。那么关于本文章的回到顶部按钮是一个什么组件呢?答案很明显,它是一个功能性的组件,因为设计它的目的:是为了让用户通过点击来使滚动条从页面从底部回到顶部。
2. 场景分析
就是明确你所封装的组件需要用在什么地方?以回到顶部按钮为例,那么用到它的主要场景:就是页面内容较长,需要向下滚动浏览,且回到顶部时,可以一步到位(不用费手指地滑鼠标向上滚)。
3. 状态分析
这一步骤,一般多用于封装装饰性组件。例如,按钮组件,它一般有如下几个状态:
默认状态
成功状态
信息状态
警告状态
危险状态
就回到顶部这种按钮形式的组件而言,我们只需一个默认状态(也就是初始化)。例如,距离页面底部或右边距的距离是多少,滚动高度为多少时显示按钮等。
4. 形态分析
主要指你封装的组件展示出来是什么样子(也就是 css 样式)。一般而言,按钮组件都会有一些形状样式和动画效果以供选择,例如:
圆形
正方形
淡入淡出过渡动画
而我们的回到顶部按钮组件,则打算通过 slot(插槽)的方式让开发者自行设计,这样的组件样式就不会只固定为有限的几种,而是姹紫嫣红。
5. 尺寸大小
通常情况下,按钮形态的组件都会有几个不同的尺寸以供选择。
small —— 小
medium —— 中等
large —— 大
由于打算让开发者能够自定义,所以这里也就不必刻意设计可选的大小。
6. 事件监听函数
在封装 vue 组件时,一般情况下,都会给其设置一些事件监听函数以便实现某些操作。
7. 暴露对外属性和事件
通过上述的一系列分析,我们可能会暴露出以下属性和事件监听函数。
属性
事件
代码实现
注意,整个组件除了为其增添了一个 transition-name
过渡动画属性以外,再无其它更改。
HTML 结构布局
<template><transition:name="transitionName"><divv-if="visible":style="{'right':styleRight,'bottom':styleBottom}"class="el-backtop"@click.stop="handleClick"><!--插槽中的默认样式,可以根据个人喜好更换,这需要在使用组件时传入--><slot><el-iconname="caret-top"/></slot></div></transition></template>
js 代码
代码中引入的 throttle(节流)函数,主要是防止用户不断地重复点击按钮触发滚动函数。大家可以通过 npminstallthrottle-debounce--save
在项目中安装引入,也可以像我在代码中写的一样:通过文件方式引入,前提是你得先下载(本人准备的 demo 中就有,需要的可以自取)。若是,同学们对节流防抖感兴趣的话,不妨看看我写的相关文章。
<script>//节流,确保一定时间段内只会调用一次事件处理函数。防止用户重复性点击。importthrottlefrom'./js/throttle'//设置滚动动画效果constcubic=value=>Math.pow(value,3)consteaseInOutCubic=value=>value<0.5?cubic(value*2)/2:1-cubic((1-value)*2)/2exportdefault{name:'ElBacktop',props:{//滚动高度visibilityHeight:{type:Number,default:200},//触发滚动的对象target:[String],//页面右边距距离right:{type:Number,default:40},//页面底部距离bottom:{type:Number,default:40},//过渡动画transitionName:{type:String,default:'el-fade-in'}},data(){return{el:null,//触发滚动的对象container:null,visible:false//控制组件显示}},computed:{//利用计算属性,监听bottom和right的值styleBottom(){return`${this.bottom}px`},styleRight(){return`${this.right}px`}},mounted(){//初始化this.init()//生成节流函数并返回this.throttledScrollHandler=throttle(300,this.onScroll)//监听scroll事件this.container.addEventListener('scroll',this.throttledScrollHandler)},//销毁钩子beforeDestroy(){//移除scroll事件this.container.removeEventListener('scroll',this.throttledScrollHandler)},methods:{//初始化,主要是获取滚动的对象init(){this.container=documentthis.el=document.documentElementif(this.target){this.el=document.querySelector(this.target)if(!this.el){thrownewError(`targetisnotexisted:${this.target}`)}this.container=this.el}},//监听滚动值,用于显示和隐藏回到顶部按钮组件onScroll(){constscrollTop=this.el.scrollTopthis.visible=scrollTop>=this.visibilityHeight},//点击事件handleClick(e){this.scrollToTop()this.$emit('click',e)//触发父级监听事件函数click},//滚动函数scrollToTop(){constel=this.el//滚动对象constbeginTime=Date.now()//开始滚动的时间constbeginValue=el.scrollTop//滚动距离//执行动画constrAF=window.requestAnimationFrame||(func=>setTimeout(func,16))//更新动画的回调函数constframeFunc=()=>{//控制动画进度constprogress=(Date.now()-beginTime)/500//progress大于1,则滚动动画执行完成,滚动条回到顶部if(progress<1){el.scrollTop=beginValue*(1-easeInOutCubic(progress))rAF(frameFunc)}else{el.scrollTop=0}}//回调,持续执行滚动动画rAF(frameFunc)}}}</script>
使用方式
Elementui 的回到顶部组件是没有 transition-name
过渡动画属性的,这里我稍作更改,为其添加了上去(完全照搬,太不像话,就加了一个,嘿嘿...)。
//方式一<BackTop:bottom="100"transition-name="el-fade-in-linear"><divstyle="{height:100%;width:100%;background-color:#f2f5f6;box-shadow:006pxrgba(0,0,0,.12);text-align:center;line-height:40px;color:#1989fa;}">UP</div></BackTop>//方式二<BackTop:bottom="100"transition-name="el-fade-in-linear"></BackTop>
最后
文章并没有什么深邃的东西值得探讨,主要是为和同学们分享我个人封装 vue 组件的一些感悟。若有不妥之处,还请担待。