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

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

重构:插件化



组件设计比较复杂的点往往在于控制的地方和组件本身有一定的耦合。


比如说上篇轮播图显示第几个图片,第几个小圆点就会标红,它们之间的状态就是耦合的,所以说我们需要解耦:


  1. 将用户控制元素(小圆点和左右箭头)抽取成插件
  2. 插件和组件之间通过依赖注入的方式建立联系


核心就是通过插件注册来实现依赖注入,插件初始化依赖于组件,而组件并不知道插件的存在:


registerPlugins(...plugins) {
  plugins.forEach(plugin => plugin(this));
}
复制代码


然后把原本在构造器中的函数抽取成插件:


image.png


类增加一个addEventListener()的API:


addEventListener(type, handler) {
  this.container.addEventListener(type, handler);
}
复制代码

最后调用即可:


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


这样以来用户控制就解耦了,当PM有新的需求时,我们可以仅删除slider.registerPlugins()中的插件或者创建新的插件再添加。

但是问题是我们还要删除对应的HTML代码,这样还是要修改很多地方,所以下一步我们要把HTML模板化


重构:模板化


现在HTML部分只需要保留一个div:


<div id="my-slider" class="slider-list"></div>
复制代码

在类中实现一个render函数来进行模板化的渲染,通过传入的参数返回正确的HTML模板:


constructor(id, opts = { images: [], cycle: 3000 }) {
  this.container = document.getElementById(id);
  this.options = opts;
  this.container.innerHTML = this.render();
  this.items = this.container.querySelectorAll('.slider-list__item, 
                                              .slider-list__item--selected');
  this.cycle = opts.cycle || 3000;
  this.slideTo(0);
}
render() {
  const images = this.options.images;
  const content = images.map(image => `
      <li class="slider-list__item">
        <img src="${image}"/>
      </li>    
    `.trim());
  return `<ul>${content.join('')}</ul>`;
}
复制代码

这样参数也可以自由设定多张图片,这里我们把它添加到5张:


const slider = new Slider('my-slider', {
  images: [
    'https://gitee.com/mancuojie/typo/raw/master/202201241731487.jpg',
    'https://gitee.com/mancuojie/typo/raw/master/202201241731486.jpg',
    'https://gitee.com/mancuojie/typo/raw/master/202201241731485.jpg',
    'https://gitee.com/mancuojie/typo/raw/master/202201241731484.jpg',
    'https://gitee.com/mancuojie/typo/raw/master/202201241731483.jpg'],
  cycle: 3000
});
slider.registerPlugins(pluginController, pluginPrevious, pluginNext);
slider.start();
复制代码


另外插件也要实现自己的render()函数,与组件同步:


image.png


通过action()正确初始化插件数据:


registerPlugins(...plugins) {
  plugins.forEach(plugin => {
    const pluginContainer = document.createElement('div');
    pluginContainer.className = '.slider-list__plugin';
    pluginContainer.innerHTML = plugin.render(this.options.images);
    this.container.appendChild(pluginContainer);
    plugin.action(this);
  });
}
复制代码


这样我们就可以通过传参和修改插件注册来满足不同需求,大大增强了扩展性。


重构:组件框架



组件模板化之后,我们可以在做一层抽象,将组件模型抽象出来进一步提升通用性和扩展性。


image.png


class Component{
  constructor(id, opts = {name, data:[]}){
    this.container = document.getElementById(id);
    this.options = opts;
    this.container.innerHTML = this.render(opts.data);
  }
  registerPlugins(...plugins){
    plugins.forEach(plugin => {
      const pluginContainer = document.createElement('div');
      pluginContainer.className = `.${name}__plugin`;
      pluginContainer.innerHTML = plugin.render(this.options.data);
      this.container.appendChild(pluginContainer);
      plugin.action(this);
    });
  }
  render(data) {
    /* abstract */
    return ''
  }
}
class Slider extends Component {
  ...
}
复制代码


改进空间



  1. CSS模板化
  2. 将组件插件结构统一,也就是不再区分组件和插件,全部都是组件,组件和组件之间可以结合成一个大的组件,然后解决父组件和子组件的状态同步和消息通信,就可以完成一个相对完整的多层级的组件框架。
目录
相关文章
|
2月前
|
前端开发 数据安全/隐私保护
crypto-js中AES的加解密封装
文章介绍了如何在前端使用crypto-js库进行AES加密和解密,提供了加解密的函数封装示例,并演示了如何加密和解密字符串或对象。
186 1
crypto-js中AES的加解密封装
|
3月前
|
JavaScript 前端开发 开发者
哇塞!Vue.js 与 Web Components 携手,掀起前端组件复用风暴,震撼你的开发世界!
【8月更文挑战第30天】这段内容介绍了Vue.js和Web Components在前端开发中的优势及二者结合的可能性。Vue.js提供高效简洁的组件化开发,单个组件包含模板、脚本和样式,方便构建复杂用户界面。Web Components作为新兴技术标准,利用自定义元素、Shadow DOM等技术创建封装性强的自定义HTML元素,实现跨框架复用。结合二者,不仅增强了Web Components的逻辑和交互功能,还实现了Vue.js组件在不同框架中的复用,提高了开发效率和可维护性。未来前端开发中,这种结合将大有可为。
142 0
|
20天前
|
JavaScript 前端开发 API
探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
【10月更文挑战第5天】探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
|
2月前
|
设计模式 JavaScript
JS发布订阅模式封装(纯手工)
发布订阅模式是JS常用的设计模式,在面试中也会经常遇到,以下是我的手写实现方式,经测试效果不错,小伙伴们们可以直接拷贝使用。
|
2月前
|
Web App开发 JavaScript 前端开发
用 JavaScript 创建 XPCOM 组件
用 JavaScript 创建 XPCOM 组件
|
3月前
|
JavaScript 前端开发 测试技术
[译]: Vue.js 函数式组件:what, why & when?
[译]: Vue.js 函数式组件:what, why & when?
[译]: Vue.js 函数式组件:what, why & when?
|
3月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
130 0
|
3月前
|
JavaScript 开发者
揭秘Vue.js生命周期钩子:它们是如何掌控组件的生与死?
【8月更文挑战第30天】Vue.js 的生命周期钩子是开发者必须掌握的关键概念,它涵盖了组件从创建、挂载、更新到销毁的整个过程,提供了在特定时机操作DOM、获取数据或执行逻辑的能力。从 `beforeCreate` 到 `unmounted`,每个阶段都有特定的任务:如 `created` 适合异步数据获取,`mounted` 用于DOM操作,而 `beforeUnmount` 则用于清理资源。
24 0
|
3月前
|
JavaScript 前端开发
揭秘Vue.js组件魔法:如何轻松驾驭前端代码,让维护变得轻而易举?
【8月更文挑战第30天】本文探讨了如何利用Vue.js的组件化开发提升前端代码的可维护性。组件化开发将复杂页面拆分为独立、可复用的组件,提高开发效率和代码可维护性。Vue.js支持全局及局部组件注册,并提供了多种组件间通信方式如props、事件等。通过示例展示了组件定义、数据传递及复用组合的方法,强调了组件化开发在实际项目中的重要性。
37 0
|
3月前
|
存储 缓存 自然语言处理
深入理解JS | 青训营笔记
深入理解JS | 青训营笔记
38 0