概述
文章目录
- 按钮
- 输入框
- tabs选项卡
- toast提示
- Popover
- 遇到的问题
前面已经有按钮为例子搭建的组件库,这里记录几个组件的封装思路(持续更新)
按钮
感觉涟漪效果挺有趣的,就加进来了,简单分析一下
在按钮组件中使用canvas组件(需要另外封装好)
<!-- 涟漪效果 -->
<por-canvas globalListen v-if="press"></por-canvas>
canvas组件中主要就两个方法,绘制和清除。
点击按钮在绘制前会先进行清除,因为可能是二次点击
点击产生涟漪效果后,对document进行监听点击事件,如果点击了页面其他,就清除canvas效果
注意
(1)点击事件的冒泡问题,当document监听点击事件的时候,事件还在冒泡阶段,会被直接触发,所以需要设置为捕获阶段触发
document.addEventListener("click", this.onClickDocument, true);
(2)因为button组件已经有hover效果,这里需要设置为和hover前一致,也就是去掉hover效果。
输入框
-
只读、提示、禁止输入
这两个可以通过动态绑定属性readonly、title和disabled实现
-
错误提示
传入error参数,v-if判断error为存在时,显示error错误信息
<div v-if="error"> <por-icon icon="icon-cuowu"></por-icon> <span class="error-message">{{error}}</span> </div>
-
保证Vue中的v-model正常使用
监听change事件,通过$emit触发change(上一级),将value向上传递
@change="$emit('change', $event.target.value)" @input="$emit('input', $event.target.value)"// 同input
还有focus和flur事件,保证输入框正常监听这些事件
tabs选项卡
tabs由五个标签组成:
<por-tabs :selected="selected">
<por-tabs-head>
<por-tabs-item name="1">1</por-tabs-item>
<por-tabs-item name="2">2</por-tabs-item>
<por-tabs-item name="3" disabled>3</por-tabs-item>
</por-tabs-head>
<por-tabs-body>
<por-tabs-pane name="1">content 1</por-tabs-pane>
<por-tabs-pane name="2">content 2</por-tabs-pane>
<por-tabs-pane name="3">content 3</por-tabs-pane>
</por-tabs-body>
</por-tabs>
data(){
return{
selected: '1'
}
}
-
item和pane如何匹配
“选择”事件
tabs提供eventBus,通过Provide向下传递,子组件通过inject获取
head在eventBus上注册“选择”事件,更新线条位置
item在eventBus上注册“选择”事件,添加active类名
pane在eventBus上注册“选择”事件,name与selected相同时,则显示selected匹配
使用tabs组件的使用动态绑定selected属性,name与selected相同的item组件添加样式类名,pane组件显示
匹配过程
初始化:找到name值与selected相同组件
在挂载阶段遍历子组件,找到head组件,再遍历head组件,找到name与selected相同的 子组件,触发eventBus中的“选择事件”,传入name值,对应name值的item组件修改式, 对应name值的pane组件展示
点击:传递item组件的name属性值
item组件绑定点击事件,触发“选择”事件,传入name值,实现切换。
-
线条移动
线条位于head组件中,根据选中的item组件与head组件与左侧窗口距离,计算出线条的左侧偏移量,宽度为item组件的宽度。(bottom为0,height为2px不用计算) -
竖直模式
direction属性控制水平还是竖直
tabs组件修改为左右两栏形式,简单使用flex布局
head组件,修改flex主轴为竖直方向
线条需要修改位置的计算方式(left变为top等),还有宽高之类的进行对调。
toast提示
- 自动关闭
由auto属性决定,默认为5,即5秒后关闭
在mouted钩子中执行关闭方法,即开始计时。因为mouted说明toast已经创建完成。
如果auto属性为false,则点击,触发关闭方法
关闭后,调用this.$destroy()销毁组件
- 引入
toast还需要以插件的形式引入,不然没有$toast方法
import { Plugin } from './packages/index'
Vue.prototype.$toast = Plugin
Popover
<por-popover position="bottom">
<por-button>下方弹出</por-button>
<template slot="content">
弹出内容
</template>
</por-popover>
- 点击触发
点击popover包裹的按钮,触发点击事件,改变visible属性,通过v-if对visible进行判断决定浮层是否显示
因为DOM是动态生成的,而且不一定需要该点击事件。所以需要通过$ref和addEventListener添加
this.$refs.popover.addEventListener('click', this.onClick)
hover触发,同上
- 浮层位置
根据触发按钮的位置(相对页面视口),确定大致位置(紧靠按钮下边或右边)
然后‘top’, ‘bottom’, ‘left’, 'right’几个值,使用transform进行偏移
如在上面弹出
transform: translateY(-100%);
margin-top: -10px;
下面弹出
margin-top: 10px;
左右位置的实现也类似
- 三角样式
// 弹出层上样式
&::before, &::after {
content: '';
display: block;
border: 10px solid transparent;
width: 0;
height: 0;
position: absolute;
}
// 对应top位置的样式
&::before, &::after {
left: 10px;
}
&::before {
border-top-color: black;
border-bottom: none;
top: 100%;
}
&::after {
border-top-color: white;
border-bottom: none;
top: calc(100% - 1px);
}
拆解一下:
before伪元素相当于添加了一个黑色三角形
// 三角形:宽高都为0,border为透明,只有一边有颜色,形成三角形
&::before {
content: '';
display: block;
width: 0;
height: 0;
border: 10px solid transparent;
border-top-color: black;
border-bottom: none;
position: absolute;
top: 100%;
}
after伪元素相当于增加了一个白色的三角形
白色三角形将黑色三角形覆盖,区别是偏移相差1px,形成黑色三角边框
&::after {
content: '';
width: 0;
height: 0;
display: block;
border: 10px solid transparent;
border-top-color: white;
position: absolute;
top: calc(100% - 1px);
}
然后‘top’, ‘bottom’, ‘left’, 'right’具体位置,修改对应的参数
遇到的问题
- 涟漪效果组件,通过点击事件在document上进行监听点击事件的时候。注意设置为捕获阶段触发,不然会在本次事件冒泡时直接触发。
- 选项卡组件修改为竖直模式时,重点在于线条位置的改变:需要从水平变为竖直。除了修改css之外,还要对位置计算进行修改。我一开始先改了位置计算(点击前和点击后),然后修改css,导致位置一直不符合。因为同时修改了两个方面,导致思路有些混乱。后面先确定初始位置,然后对点击切换后的位置进行调整,很快解决问题。
- tabs线条和popover出现位置需要使用到getBoundingClientRect()获取元素相对于视窗的位置集合。
- 动态绑定多个类名可以使用computed维护一个数组。
- 三角形就是宽高都为0的盒子,设置边框。其中三边的边框为透明,只有一边有颜色。黑白两个三角形重叠且相差1px会形成三角边框。
最后
以上就是飞快香烟为你收集整理的组件库系列四:组件封装思路的全部内容,希望文章能够帮你解决组件库系列四:组件封装思路所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复