嗨,我是你稳定更新、专注前端的勾勾。你也可以叫我勾崽。
微信小程序自定义组件的开发细节非常多,需要重点关注一下几个核心点:
- 自定义组件的资源管理;
组件的生命周期;
组件间的通信流程。
目前流行的几个前端框架( Vue / React / Angular )都在一定程度上遵循了Web Components 规范,微信小程序的自定义组件也是如此。
自定义组件的优势
提高代码可复用性
这是组件化最直接的优点,如果不用组件,每次遇到相同的业务场景都需要重新编写代码,而被抽离后的组件可以在其适用的场景内被重复使用,很大程度上降低了开发耗时。
降低代码维护难度
想象一下,假如一个页面的所有 UI 源码都集中在同一个 HTML 文件中,当页面中的导航栏出现 Bug,你需要在上千行甚至上万行的 HTML 文件中找到导航栏对应的 HTML 标签。
如果将导航栏抽离为一个组件,那么你仅仅需要在这个组件内寻找。这类案例在工作中普遍存在,通过这个例子可以充分说明组件化在降低代码维护难度方面的优势。
降低系统重构难度
《重构-改善既有代码的设计》提到:重构并不是当系统复杂度提升到一定程度难以维护时的一次性行为,而是一种高频的、小规模的日常行为。
直白点儿说就是:应该不断通过重构来改善系统,不管重构的范围有多小。但是这种实践方式对于代码的可维护性有很大的挑战,这也间接说明了组件化对重构工作的正面影响:通过提高代码的可维护性,间接降低了系统的重构难度。
微信小程序的自定义组件是组件化思想在小程序开发领域的一种具体落地实践,具有上面三个优点。而且不论是工作还是面试,能否开发出优秀的自定义组件是衡量小程序开发者(甚至前端开发者)的核心指标之一。
需要注意的核心问题
自定义组件的资源管理
创建微信小程序自定义组件需要使用 Component 构造器,这是微信小程序结构体系内最小粒度的构造器,外层是 Page 构造器,最外层的是 App 构造器。
从外到内依次是 App > Page > Component,每次递进是 1:N 的关系:
- 1 个 App(也就是 1 个小程序)可包含 N( N >= 1 )个 Page;
- 1 一个 Page 可包含N(N>=1)个 Component。
每个自定义组件的资源必须包括四个基本文件:
- 用于描述组件结构的 wxml 文件;
- 用于描述组件样式的 wxss 文件;
- 用于描述组件行为的 js 文件;
- 用于声明组件配置的 json 文件。
跟传统前端开发相比,小程序自定义组件的 wxml 和 wxss 文件的编写方式与 HTML 和 CSS 编写基本类似,不要特别关注,差异性主要体现在 js 和 json 文件上。
在 json 文件中必须通过 component 字段声明此组件为自定义组件,如下:
{
"component": true
}
js 文件中通过 Component 构造器创建组件的逻辑实体,如下:
Component({
behaviors:[],
properties:{},
data: {},
lifetimes: {},
pageLifetimes: {},
methods: {}
});
除 4 个基础文件以外,自定义组件还可以包含一些其他必要的资源,比如图片。
你可以看到,除了 wxml/wxss/js/json 文件以外,还有两个图片文件,在 wxml 中可以直接使用相对目录引用,如下:
<image src="./photo.png"></image>
自定义组件的生命周期
对一个组件来说,生命周期指的是这个组件从被创建到销毁的过程,在这个过程中的里程碑阶段暴露出一些钩子函数,方便开发者针对不同阶段编写逻辑,这些函数就是所谓的“生命周期函数”。
微信小程序自定义组件的生命周期函数有以下几个:
跟 Vue 和 React 相比,小程序自定义组件的生命周期更贴近 Web Components 规范。
对比 Web Components 规范和小程序自定义组件的生命周期,两者有一定相似之处但并不完全一致,总结出这样几点:
attached 和 detached 函数分别对应 Web Components 规范的connectedCallback 和 disconnectedCallback,功能上是一致的;
moved 函数与 Web Components 规范的 adoptedCallback 类似但作用并不完全相同。由于小程序不支持 iframe,所以不存在组件在文档范畴上的迁移,只能在同一个文档的不同父节点之间迁移。所以也就不存在 adopted 状态,moved 函数可以理解为adopted 的一种变体;
小程序自定义组件独有的生命周期函数,created、ready 和 error;
Web Components 规范独有的生命周期函数,attributeChangedCallback。
组件间的通信流程
与 Vue/React 不同,小程序没有类似 Vuex 或 Redux 数据流管理模块,所以小程序的自定义组件之间的通信流程采用的是比较原始的事件驱动模式,即子组件通过抛出事件将数据传递给父组件,父组件通过 properties 将数据传递给子组件。
除了事件驱动的通信方式以外,小程序还提供了一种更加简单粗暴的方法:
父组件通过selectComponent 方法直接获取某个子组件的实例对象,然后就可以访问这个子组件的任何属性和方法了。随后将这个子组件的某个属性通过 properties传递给另外一个子组件。
相较而言,事件驱动的方法更加优雅,在流程上也更加可控,所以通常建议使用事件驱动的通信方式。
想要真正理解组件化背后的思想,建议你尝试参照小程序的文档实现一个小程序自定义组件。
本文暂时没有评论,来添加一个吧(●'◡'●)