【青训营】写好JS——组件封装(上)

简介: 【青训营】写好JS——组件封装(上)

组件是指Web页面上抽出来一个个包含模版(HTML)、功能(JS)和样式(CSS)的单元。好的组件具备封装性、正确性、扩展性、复用性。


例子:轮播图



如果要你用原生JS写一个电商或视频网站上常见的轮播图,应该怎么实现?怎么封装成组件?怎么让它的扩展性和复用性更高?


image.png


1. 结构设计



轮播图是一个典型的列表结构,我们可以用无序列表ul>li*4来实现,然后根据效果图插入4张图片即可:



这里我们使用的命名是一种CSS的书写规范,叫做BEM,是英文Block-Element-Modifier的简写,这一规范采用三个部分来描述规则,其中:


  • __:双下划线用来连接块和块的子元素
  • -:单中划线仅作为连字符使用,连接块或元素或修饰符的多个单词
  • --:双中划线用来连接块或元素的状态

这样命名可以将用户界面分隔为独立的块,从而使开发复杂的UI界面变得更简单,代码可读性也更强。


上面的HTML结构中,我们使用a元素分别表示上一张和下一张:


<a class="slider__previous"></a>
<a class="slider__next"></a>
复制代码

span*4表示底部的四个小圆点:


<div class="slider__control">
  <span class="slider__control-buttons--selected"></span>
  <span class="slider__control-buttons"></span>
  <span class="slider__control-buttons"></span>
  <span class="slider__control-buttons"></span>
</div>
复制代码


2. 展现效果



根据效果图我们继续添加CSS样式,首先设置宽高,隐藏列表样式:


.slider {
  position: relative;
  width: 790px;
  height: 340px;
}
.slider ul {
  list-style-type:none;
  position: relative;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}
复制代码

将图片重叠,只显示.slider__item--selected


.slider__item,
.slider__item--selected {
  position: absolute;
  transition: opacity 1s;
  opacity: 0;     /* 完全透明 */
  text-align: center;
}
.slider__item--selected {
  transition: opacity 1s;
  opacity: 1;
}
复制代码

能够上下切换的左右箭头:


最后定义底部的4个小圆点:


3. API设计



API的设计应保证原子操作,职能单一,满足灵活性。


我们先简单分析一下需求:


  1. 图片循环播放,每张停留若干时间
  2. 点击左右箭头可以上下切换
  3. 鼠标悬浮在底部小圆点上时会跳到对应图片
  4. 小圆点也会随着图片滚动


根据需求和月影大大的设计要求,我们设计了几个组件API:


将其封装成一个类:


然后通过setInterval()实现循环播放,间隔为3秒:


const container = document.querySelector('.slider');
const slider = new Slider(container);
setInterval(() => {
  slider.slideNext();
}, 3000);
复制代码


4. 用户控制



在JS代码中,一个方法一般来说最多只能有15行代码,超过了就需要重构。


实现了API后,我们需要实现用户控制,根据需求修改构造器:


image.png


用定时器来实现stop()start(),当鼠标移动到小圆点上(mouseover),判断是第几个小圆点,停止循环播放,切换到对应图片,当鼠标移出后(mouseout)再开始循环。


start() {
  this.stop();
  this._timer = setInterval(() => this.slideNext(), this.cycle);
}
stop() {
  clearInterval(this._timer);
}
复制代码

然后我们处理自定义的slide事件,修改slideTo()


slideTo(idx) {
  ...
  // 触发自定义事件slide
  const detail = {index: idx};
  const event = new CustomEvent('slide', {bubbles: true, detail});
  this.container.dispatchEvent(event);
}
复制代码

最后将调用过程修改一下,组件的全部功能就完成了。


const container = document.querySelector('.slider');
const slider = new Slider({container});
slider.start();
复制代码

通过轮播图组件编写过程,我们可以总结一下组件设计的一般性步骤:


  1. 结构设计和展现效果(HTML&CSS)
  2. 设计组件API
  3. 设计用户控制流程


我们实现的轮播组件实现了封装性和正确性,但是缺少了可扩展性,这个组件只能满足自身的使用,很难扩展到其他的组件。而且当有功能变化时,也需要修改其自身内部的代码。


比如当产品经理希望将图片下方的小圆点去掉只保留左右箭头时,在这个版本中我们就需要注释或修改所有与小圆点相关的代码,而且当有新的用户控制需求时,我们都需要涉及核心代码的修改,所以如何避免这样的修改,让组件具备可扩展性和复用性就是我们下节要做的事情了。

目录
相关文章
|
2月前
sd.js 2.0封装:更加简化请求传参内容(逐步废弃、逐渐日落2024.01.02)
sd.js 2.0封装:更加简化请求传参内容(逐步废弃、逐渐日落2024.01.02)
|
2月前
|
JavaScript
JS封装节流函数
JS封装节流函数
32 0
|
2月前
|
JavaScript
Vue.js 修饰符:精准控制组件行为
Vue.js 修饰符:精准控制组件行为
|
5天前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包是函数访问外部作用域变量的能力体现,它用于封装私有变量、持久化状态、避免全局污染和处理异步操作。
【6月更文挑战第25天】JavaScript闭包是函数访问外部作用域变量的能力体现,它用于封装私有变量、持久化状态、避免全局污染和处理异步操作。闭包基于作用域链和垃圾回收机制,允许函数记住其定义时的环境。例如,`createCounter`函数返回的内部函数能访问并更新`count`,每次调用`counter()`计数器递增,展示了闭包维持状态的特性。
20 5
|
19天前
|
JavaScript
Vue.js中实现自定义组件的双向绑定
Vue.js中实现自定义组件的双向绑定
|
19天前
|
JavaScript
Vue.js中使用作用域插槽实现自定义表格组件
Vue.js中使用作用域插槽实现自定义表格组件
|
3天前
|
JavaScript 前端开发
程序技术好文:第一百三十八节,JavaScript,封装库
程序技术好文:第一百三十八节,JavaScript,封装库
|
26天前
|
存储 移动开发 JavaScript
uni-app 64聊天类chat.js封装(一)
`uni-app` 是一个使用 Vue.js 开发所有前端应用的框架,可以编译到iOS、Android、H5以及各种小程序等多个平台。当你提到“64聊天类`chat.js`封装”时,我假设你希望了解如
|
16天前
JS-函数封装数组求和案例
JS-函数封装数组求和案例
|
2月前
|
JavaScript 前端开发
JavaScript实现缓慢动画的封装
JavaScript实现缓慢动画的封装
18 0