什么是 Custom Elements?
Custom Elements 是 Web Components 的一部分,它提供了一种可以定义自己的 HTML 元素的 API。可以理解为我们可以自己去定制一个 HTML 标签,然后在页面中使用这个标签作为一个元素来使用。我们可以基于 Custom Elements 来开发出可复用的组件。
为什么要使用 Custom Elements?
使用 Custom Elements 可以轻松地定制、创建和重用组件,而不需过多关注组件内部实现逻辑。自定义元素还可以为开发人员提供更加模块化的思考方式,使代码更加容易维护。
在传统的 web 开发中,我们无法自定义 HTML 标签,要达到自己想要的 UI 效果,必须使用 CSS 样式,在布局、交互方面容易出现矛盾和问题。而 Custom Elements 解决了这些问题。
Custom Elements 生命周期
在 Custom Elements 中,有以下生命周期钩子:
constructor() 在元素首次被创建时调用,用于初始化相关属性、添加事件等。
connectedCallback() 当元素首次被插入到文档 DOM 时被调用,此时可以进行一些 DOM 或 CSS 的操作,例如渲染自定义元素的内容、调用数据接口等等。
disconnectedCallback() 当元素被移除时调用,此时可以进行一些释放资源的操作,例如清理定时器、释放内存等等。
attributeChangedCallback() 当自定义元素的某个属性值变化时,此方法会被调用。
使用 Custom Elements 构建组件
我们可以使用 Custom Elements 来构建出一个组件,该组件有自己的生命周期。
创建一个简单的组件
-- -------------------- ---- ------- -------- ----- ------------ ------- ----------- - ------------- - -------- ----------- - ------------------------ --------- -- -- ------ --- --------------------- - --------------- ----------------- -- ------ - - -------------------------------------- -------------- -- ------- --------- -------------------------------
我们创建了一个 CustomButton
组件,并在其构造函数中定义了其内容和 shadow DOM。然后我们使用 customElements.define()
方法来注册我们的组件,并为其定义一个名称 custom-button
。最后,在页面中,我们可以简单地使用 <custom-button></custom-button>
标记来使用这个组件。
添加生命周期
现在我们来为组件添加生命周期方法,以便在组件各个生命周期中做出不同的行为。
-- -------------------- ---- ------- -------- ----- ------------ ------- ----------- - ------------- - -------- ----------- - ------------------------ --------- -- -- ------ --- --------------------- - --------------- ----------------- -- ------ ------------------------- -------------- -- ---------- - ------------------- - ------------------------- ------------ - ---------------------- - ------------------------- --------------- - ---------------------------------- ------- ------- - --------------------- - --------- ------- ---- -- ------- - -- -- -------- - ------ --- -------------------- - -- ------ ------ ------------ -------- - - -------------------------------------- -------------- -- ------- --------- -------------- --------------- ------------------------------
在上面的代码中,我们添加了 logged
、connectedCallback
、disconnectedCallback
、attributeChangedCallback
四个生命周期方法,并添加了一些简单的日志输出。我们还定义了 observedAttributes
方法,以便为我们的组件的属性变化添加事件监听。在页面中,我们也添加了一些自定义元素属性,并在属性变化时打印出相应的日志。
优化组件性能
组件的性能优化是一个复杂的过程,我们这里基于 用户体验 - 网页性能 此模块,简单介绍一下性能优化点。
有使用到阻塞资源的,加 loading
部分组件使用了资源加载,比如图片、ajax、网络请求或者简单的计算。如果放到代码底部加载,用户在使用组件的时候一定会有等待的时间。所以如果组件内依赖了资源加载,最好使用 loading
来提醒用户。
-- -------------------- ---- ------- ------- --------------- - -------- ----- ---------------- ------- ------------ ------- ----------- ------- ------ ----- ---------- ----- ------- ----- - -------- -------- ----- ------------- ------- ----------- - ------------- - -------- ------------ - ------------------------------ ---------------------- - ----------------- ---------------------- - ------------- ------------------- ----- ------ ----------------------------- -- -------- ------------- -- - ---------------- -- ------ - ---------- - -- ---- -- --------------------------------------- --------------- --------- ---------------------------------
我们可以看到,我们设置了一个预加载动画 Loading...
。在组件的 constructor
中,我们添加了一个模拟数据加载的方法 loadData()
,并使用 setTimeout()
来模拟异步加载数据,在展示数据之前预留时间为 1 秒钟,瞬间反应加载。在 loadData()
方法中,我们会加载真实数据并对其进行展示。
使用防抖函数减少触发次数
有些组件需要进行实时的搜索,比如 AutoComplete
。如果我们每次输入字符都触发一次数据请求,可能会造成性能问题。这个时候我们可以使用防抖函数来优化性能。
防抖函数的主要思想在于,当我们持续触发某一函数时,在一段时间内只会触发一次。我们可以使用 JavaScript 中的 setTimeout()
函数来实现防抖函数。
-- -------------------- ---- ------- -------- ----- ------------------ ------- ----------- - ------------- - -------- ---------- - -------------------------------- --------------- - ------- ------------------------------------ ----------------------------------------- ------------------- ----- ------ --------------------------- - ----------- - ---------------------- ---- -------- -------------------- - ------------ ---- - ----- - --- ----- - ----- ------ ----------------- - -------------------- ----- - ------------- -- - -------------- ------ -- ------ -- - - --------------------------------------------- -------------------- --------- ---------------------------------------------
在上面的代码中,我们定义了一个 CustomAutoComplete
组件,它在其构造函数中创建了一个输入框,并为其添加了 input
事件监听函数。我们使用 debounce()
函数来实现防抖效果。
缓存数据减少请求
在使用一些需要请求后端接口的组件时,比如列表、卡片等,我们在多次进入页面的时候需要重新请求,造成多次请求,可能会对性能造成压力。所以我们可以开启缓存机制,将请求后的数据存储在浏览器中,等下一次打开页面时从缓存中读取。
-- -------------------- ---- ------- -------- ----- ---------- ------- ----------- - ------------- - -------- ------------------- ----- ------ --- ----- -------- - ------------------- -- -------------------------------- - ------------------------- - -------------------------------------------------------- - ---- - ---------------- - - ---------- - -- ---- ---- -- ----- ---- ---- ------ --- ----- ----- - -- ----- -------- --------- ------------- -- ------ ------- ---------------------------------------- ---------------------- ------------------------- - ------------------- - ------------ - -- ---- ---- -- --------- ---- ---- ---- - - ------------------------------------ ------------ --------- ---------------------------
在上面的代码中,我们创建了一个 CustomCard
组件,并在其构造函数中检查缓存中是否存在我们的数据。如果有,我们将其使用 localStorage
对象从缓存中读取出来,并使用 render()
方法将其渲染。如果没有,我们使用 fetch()
来从服务器读取数据,并将返回结果存储在缓存中。
在实际的项目中,我们可以根据自己的需求自定义缓存的容量、缓存过期时间、缓存策略等等。优化性能非常重要,减少了不必要的请求和资源,不仅可以提升用户体验,同时也能减少服务器的负担。
总结
Custom Elements 是一个非常有用的 web 开发工具,能够帮助我们创建可复用、可维护的组件,并让我们能够轻松地实现 UI 动态效果和性能优化。使用 Custom Elements 来构建组件,尤其是使用生命周期管理组件,可以更好地掌控组件代码、功能和性能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6520c0cc95b1f8cacd83235d