当前位置:网站首页>前端未來趨勢之原生API:Web Components
前端未來趨勢之原生API:Web Components
2020-11-06 21:07:00 【itread01】
[原始碼解讀](https://github.com/yyx990803/vue-lit/blob/master/index.js) ```js // lit-html 模板,提供 html 模板(簡單js表示式及事件繫結)、render 渲染能力 import { render } from 'https://unpkg.com/lit-html?module' // reactivity 是vue3.0的核心,shallowReactive 淺響應,effect 可以理解為 watch,提供屬性響應及部分生命週期處理 import { shallowReactive, effect } from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js' let currentInstance export function defineComponent(name, propDefs, factory) { if (typeof propDefs === 'function') { factory = propDefs propDefs = [] } // 自定義元素 custom element,原生 API customElements.define( name, class extends HTMLElement { // 設定需要監聽的屬性 static get observedAttributes() { return propDefs } constructor() { super() // 屬性接入 vue 的響應式 const props = (this._props = shallowReactive({})) currentInstance = this // lit-html 的 html 生成的模板 const template = factory.call(this, props) currentInstance = null // bm onBeforeMount this._bm && this._bm.forEach((cb) => cb()) // shadowRoot,closed 表示不可以直接通過 js 獲取到定義的 customElement 操作 shadowRoot const root = this.attachShadow({ mode: 'closed' }) let isMounted = false effect(() => { if (isMounted) { // _bu, onBeforeUpdate this._bu && this._bu.forEach((cb) => cb()) } // 將 template 內容掛載到 shadowRoot 上 render(template(), root) if (isMounted) { // _u,onUpdated this._u && this._u.forEach((cb) => cb()) } else { isMounted = true } }) } // 首次掛載到 dom 上後的回撥,onMounted connectedCallback() { this._m && this._m.forEach((cb) => cb()) } // 解除安裝, onUnmounted disconnectedCallback() { this._um && this._um.forEach((cb) => cb()) } // 屬性監聽 attributeChangedCallback(name, oldValue, newValue) { this._props[name] = newValue } } ) } function createLifecycleMethod(name) { return (cb) => { if (currentInstance) { ;(currentInstance[name] || (currentInstance[name] = [])).push(cb) } } } export const onBeforeMount = createLifecycleMethod('_bm') export const onMounted = createLifecycleMethod('_m') export const onBeforeUpdate = createLifecycleMethod('_bu') export const onUpdated = createLifecycleMethod('_u') export const onUnmounted = createLifecycleMethod('_um') export * from 'https://unpkg.com/lit-html?module' export * from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js' ``` [shallowReactive 原始碼](https://github.com/vuejs/vue-next/blob/master/packages/reactivity/src/reactive.ts),函式註釋已經表達的很清楚了,only the root level properties are reactive。物件只有根屬性響應,換言之即,淺響應,和淺拷貝類似。 ```js /** * Return a shallowly-reactive copy of the original object, where only the root * level properties are reactive. It also does not auto-unwrap refs (even at the * root level). */ export function shallowReactive
#### input、select 等內建 html 元素 input、select 也是 web component。但是是內建的,預設看不到 shadowRoot 結構,需要開啟瀏覽器控制檯的設定,勾選`Show user agent shadow DOM`,才可以在控制檯`elements`中看到其結構。 設定
dom 結構
## web components 元件化由 3 部分組成。 - **Custom elements(自定義元素)**:一組JavaScript API,允許您定義custom elements及其行為,然後可以在您的使用者介面中按照需要使用它們。 - **Shadow DOM(影子DOM)**:一組JavaScript API,用於將封裝的“影子”DOM樹附加到元素(與主文件DOM分開呈現)並控制其關聯的功能。通過這種方式,您可以保持元素的功能私有,這樣它們就可以被指令碼化和樣式化,而不用擔心與文件的其他部分發生衝突。 - **HTML templates(HTML模板)**: `
` 和 `
可以和操作普通 DOM 一樣,利用 API 操作 Shoadow DOM。 ```js let shadow = elementRef.attachShadow({mode: 'open'}); let shadow = elementRef.attachShadow({mode: 'closed'}); ``` `open` 表示可以通過頁面內的 JavaScript 方法來獲取 Shadow DOM,如'document.querySelector('custom-info').shadowRoot'。反之,獲取不到。 更多,請參考:[Shadow DOM](https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM) ### HTML templates template 和 slot 元素可以創建出非常靈活的 shadow DOM 模板,來填充 custom element。 對於重複使用的 html 結構,可以起到簡化作用,非常有意義。 示例 ```html
[其他庫 todolist 大比拼](https://wc-todo.firebaseapp.com/)
看圖,結果不言而喻。 ## 總結 瀏覽器原生能力正在變得很強大。web component 值得擁抱一下。雖然 template 還不是很完善(不支援表示式),但這也只是白板上的一個黑點。 參考: 1. [尤大 3 天前發在 GitHub 上的 vue-lit 是啥?](https://github.com/axuebin/articles/issues/41) 2. [Web Components](https://developer.mozilla.org/zh-CN/docs/Web/Web_Components) 3. [web-components-todo](https://github.com/shprink/web-component
版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1604667905.html
边栏推荐
- Summary of common algorithms of binary tree
- 一篇文章带你了解CSS 渐变知识
- Python filtering sensitive word records
- Recommendation system based on deep learning
- Using NLP and ml to extract and construct web data
- Vuejs development specification
- It's so embarrassing, fans broke ten thousand, used for a year!
- Relationship between business policies, business rules, business processes and business master data - modern analysis
- 6.2 handleradapter adapter processor (in-depth analysis of SSM and project practice)
- vue-codemirror基本用法:实现搜索功能、代码折叠功能、获取编辑器值及时验证
猜你喜欢

It's easy to operate. ThreadLocal can also be used as a cache

一篇文章带你了解CSS3图片边框

The road of C + + Learning: from introduction to mastery

用一个例子理解JS函数的底层处理机制

零基础打造一款属于自己的网页搜索引擎

Mongodb (from 0 to 1), 11 days mongodb primary to intermediate advanced secret

每个前端工程师都应该懂的前端性能优化总结:

Python基础数据类型——tuple浅析

带你学习ES5中新增的方法

In order to save money, I learned PHP in one day!
随机推荐
这个项目可以让你在几分钟快速了解某个编程语言
Multi classification of unbalanced text using AWS sagemaker blazingtext
Windows 10 tensorflow (2) regression analysis of principles, deep learning framework (gradient descent method to solve regression parameters)
Just now, I popularized two unique skills of login to Xuemei
NLP model Bert: from introduction to mastery (1)
ES6 essence:
Mongodb (from 0 to 1), 11 days mongodb primary to intermediate advanced secret
一篇文章教会你使用Python网络爬虫下载酷狗音乐
零基础打造一款属于自己的网页搜索引擎
ES6学习笔记(二):教你玩转类的继承和类的对象
6.3 handlerexceptionresolver exception handling (in-depth analysis of SSM and project practice)
The road of C + + Learning: from introduction to mastery
From zero learning artificial intelligence, open the road of career planning!
Building and visualizing decision tree with Python
use Asponse.Words Working with word templates
Python saves the list data
一篇文章教会你使用Python网络爬虫下载酷狗音乐
Nodejs crawler captures ancient books and records, a total of 16000 pages, experience summary and project sharing
用一个例子理解JS函数的底层处理机制
Lane change detection