当前位置:网站首页>Web Components
Web Components
2022-07-05 10:21:00 【码小龙.】
Web Components
介绍
谷歌公司掌握了Chrome浏览器, 所以一直在推动浏览器的原生组件, 也就是Web Components API
相比于第三方框架, 原生组件简单直接, 不用加载任何外部模块, 代码量小
允许创建可重用的定制元素, 并且在我们的web应用中直接使用它们
核心技术组成
Custom elements 自定义元素
一组JavaScript API, 允许定义custom elements及其行为, 然后在用户界面中按照需要使用它们
Shadow DOM 影子DOM
一组JavaScript API, 用于将封装的影子DOM树附加到元素(与主文档DOM分开呈现), 并控制其关联功能
通过这种方式, 我们可以保持元素的功能私有, 这样它们就可以被脚本化和样式化, 而不用担心与文档的其它部分发生冲突
HTML template html模板
和元素使你可以编写不在呈现页面中显示的标记模板, 然后它们可以作为自定义元素结构的基础被多次重用
生命周期函数
connectedCallback
当自定义元素第一次被连接到文档DOM时被调用
disconnectedCallback
当自定义元素与文档DOM断开连接时被调用
adoptedCallback
当自定义元素被移动到新文档时被调用
attributeChangedCallback
当自定义元素的第一个属性被增加、移除或更改时被调用
实例开发
实例1:日期组件
01.png
目录结构
|-scripts
|–date.time.js
|-index.html
开发日期组件
(() => {
// 创建模板
const template = document.createElement(‘template’)
// 标签元素里面包含了我们组件里面的具体样式和DOM
template.innerHTML = `
`
// 创建自定义datetime组件类DateTime, 只要继承HTMLElement类就可以编写自定义标签/元素
class DateTime extends HTMLElement {
/**
* constructor 生命周期函数
* @description 元素创建了, 但是没有添加到页面
* @description 一般来说需要在constructor中创建初始化状态, 事件监听和创建影子DOM
*/
constructor () {
// 调用super方法, 需要使用它来调用父级的构造方法
super()
/**
* attachShadow 影子DOM
* @param open 允许外界访问
* @param closed 关闭外界获取的途径
*/
this.attachShadow({ mode: ‘open’ })
/**
* shadowRoot 影子DOM的根节点
* @description template.content 是一个游离的文档碎片
* @description cloneNode(params) params -> boolean [true|false]
* true -> 深度遍历克隆
*/
this.shadowRoot.appendChild(template.content.cloneNode(true))
}
// 初始化时间
initDateTime () {
// 获取当前的时间对象
let date = new Date()
// 创建英文月份枚举数组
let month = [‘January’, ‘February’, ‘March’, ‘April’, ‘May’, ‘June’, ‘July’, ‘August’, ‘September’, ‘October’, ‘November’, ‘December’]
// 封装配置需要使用的年月日
let dateConfig = {
date: date.getDate() >= 10 ? date.getDate() : ‘0’ + date.getDate(),
month: month[date.getMonth()],
year: date.getFullYear()
}
// console.log(dateConfig)
// datetime内容渲染显示
this.shadowRoot.querySelector(‘.datetime-box__wrap–day’).innerText = dateConfig.date
this.shadowRoot.querySelector(‘.datetime-box__wrap–month’).innerText = dateConfig.month
this.shadowRoot.querySelector(‘.datetime-box__wrap–year’).innerText = dateConfig.year
}
/**
* connectedCallback 生命周期函数
* @description 当自定义元素第一次被连接到文档DOM时被调用
* @description 元素被插入DOM的时候执行, 一般来说用来获取数据, 设置默认的显示样式或者内容
*/
connectedCallback () {
this.initDateTime()
}
}
/**
* 全局注册组件
* @description 把组件类挂载到DOM上去, 自定义标签名使用我们的组件
*/
window.customElements.define(‘date-time’, DateTime)
})()
页面引用
实例2:列表(详情)组件
02.png
目录结构
|-images
|-scripts
|–article-info.js
|–article-info-detail.js
|–article-data.js
|–script.js
|-index.html
html结构
-
-
Comment -
-
- *
-
`
class ArticleInfo extends HTMLElement {
constructor () {
super()
this.attachShadow({ mode: ‘open’ })
this.shadowRoot.appendChild(template.content.cloneNode(true))
this.initEvent()
}
/**
* 初始化事件
* @description 使用CustomEvent定义自定义事件
*/
initEvent () {
const cardInfo = this.$(‘.card-info’)
cardInfo.addEventListener(‘click’, (ev) => {
let myEventInfo = new CustomEvent(‘card-click’, {
composed: true,
bubbles: true
})
this.dispatchEvent(myEventInfo)
})
}
$(selector) {
return this.shadowRoot.querySelector(selector)
}
initRender () {
this.KaTeX parse error: Expected group after '_' at position 13: ('.card-info_̲_cover--image')…(‘.card-info__cover–title’).innerText = this.getAttribute(‘theme’)
this.KaTeX parse error: Expected group after '_' at position 13: ('.card-info_̲_avatar').src =…(‘.card-info__author’).innerText = this.getAttribute(‘author’)
this.$(‘.card-info__title’).innerText = this.getAttribute(‘title’)
}
connectedCallback () {
this.initRender()
}
}
window.customElements.define(‘arcitle-info’, ArticleInfo)
})()
开发详情组件
(() => {
const template = document.createElement(‘template’)
template.innerHTML = <img class="cover" src=""/> <span class="theme"></span> <img class="avatar" src=""/> <span class="author"></span> <span class="title"></span> <span class="comments"></span> <span class="likes"></span> <span class="shares"></span> <p class="p"></p> <button class="back">Back</button>
class ArticleInfoDetail extends HTMLElement {
constructor () {
super()
this.attachShadow({ mode: ‘open’ })
this.shadowRoot.appendChild(template.content.cloneNode(true))
this.initEvent()
}
initEvent () {
const backBtn = this.$(‘.back’)
backBtn.addEventListener(‘click’, (ev) => {
let myEvent = new CustomEvent(‘card-back-click’, {
composed: true,
bubbles: true
})
this.dispatchEvent(myEvent)
})
}
$(selector) {
return this.shadowRoot.querySelector(selector)
}
initRender () {
this. ( ′ . c o v e r ′ ) . s r c = t h i s . g e t A t t r i b u t e ( ′ c o v e r ′ ) t h i s . ('.cover').src = this.getAttribute('cover') this. (′.cover′).src=this.getAttribute(′cover′)this.(‘.theme’).innerText = this.getAttribute(‘theme’)
this. ( ′ . a v a t a r ′ ) . s r c = t h i s . g e t A t t r i b u t e ( ′ a v a t a r ′ ) t h i s . ('.avatar').src = this.getAttribute('avatar') this. (′.avatar′).src=this.getAttribute(′avatar′)this.(‘.author’).innerText = this.getAttribute(‘author’)
this. ( ′ . t i t l e ′ ) . i n n e r T e x t = t h i s . g e t A t t r i b u t e ( ′ t i t l e ′ ) t h i s . ('.title').innerText = this.getAttribute('title') this. (′.title′).innerText=this.getAttribute(′title′)this.(‘.comments’).innerText = this.getAttribute(‘comments’)
this. ( ′ . l i k e s ′ ) . i n n e r T e x t = t h i s . g e t A t t r i b u t e ( ′ l i k e s ′ ) t h i s . ('.likes').innerText = this.getAttribute('likes') this. (′.likes′).innerText=this.getAttribute(′likes′)this.(‘.shares’).innerText = this.getAttribute(‘shares’)
this.$(‘.p’).innerText = this.getAttribute(‘p’)
}
connectedCallback () {
this.initRender()
}
/**
* attributeChangedCallback生命周期函数
* @param name
* @param oldValue
* @param newValue
* @description 当自定义元素的第一个属性被增加、移除或更改时被调用
*/
attributeChangedCallback (name, oldValue, newValue) {
// console.log(name, oldValue, newValue)
this.initRender()
}
// 监听属性的变化 - 返回的每一个属性名对应的属性值发生变化, 都会触发对应的attributeChangedCallback方法
static get observedAttributes () {
return [‘id’, ‘cover’, ‘theme’, ‘avatar’, ‘author’, ‘title’, ‘comments’, ‘likes’, ‘shares’, ‘p’]
}
}
window.customElements.define(‘arcitle-info-detail’, ArticleInfoDetail)
})()
scripts.js
(() => {
let container = document.querySelector(‘.container’)
let str = ‘’
// 遍历获取所有的文章信息
cardData.forEach(item => {
str += <arcitle-info id="${item.id}" cover="${item.cover}" theme="${item.theme}" avatar="${item.avatar}" author="${item.author}" title="${item.title}"> <span slot="comments">${item.comments}</span> <span slot="likes">${item.likes}</span> <span slot="shares">${item.shares}</span> </arcitle-info>
})
// append到container中
container.innerHTML = str
document.body.addEventListener(‘card-click’, (ev) => {
let id = ev.target.id
let detailWrap = document.querySelector(‘.container-detail-wrap’)
let cardDetail = document.querySelector(‘arcitle-info-detail’)
// get arcitle data from id
let articleSelectData = cardData.filter(v => v.id === id)[0]
Object.keys(articleSelectData).forEach(key => {
cardDetail.setAttribute(key, articleSelectData[key])
})
// 动画显示文章详情页
detailWrap.style.left = 0;
detailWrap.style.opacity = 1;
})
document.body.addEventListener(‘card-back-click’, (ev) => {
let detailWrap = document.querySelector(‘.container-detail-wrap’)
// 动画显示文章详情页
detailWrap.style.left = ‘100%’;
detailWrap.style.opacity = 0;
})
})()
边栏推荐
- Activity jump encapsulation
- 【SWT组件】内容滚动组件 ScrolledComposite
- [论文阅读] KGAT: Knowledge Graph Attention Network for Recommendation
- Detailed explanation of the use of staticlayout
- 数据库中的范式:第一范式,第二范式,第三范式
- Blockbuster: the domestic IDE is released, developed by Alibaba, and is completely open source!
- 【Vite】1371- 手把手开发 Vite 插件
- 请问postgresql cdc 怎么设置单独的增量模式呀,debezium.snapshot.mo
- LSTM应用于MNIST数据集分类(与CNN做对比)
- How to plan the career of a programmer?
猜你喜欢

What is the most suitable book for programmers to engage in open source?

Window下线程与线程同步总结
![[vite] 1371 - develop vite plug-ins by hand](/img/7f/84bba39965b4116f20b1cf8211f70a.png)
[vite] 1371 - develop vite plug-ins by hand

微信核酸检测预约小程序系统毕业设计毕设(7)中期检查报告

2022年T电梯修理操作证考试题及答案

5G NR系统架构

pytorch输出tensor张量时有省略号的解决方案(将tensor完整输出)

SAP ui5 objectpagelayout control usage sharing

到底谁才是“良心”国产品牌?
![[paper reading] ckan: collaborative knowledge aware autonomous network for adviser systems](/img/6c/5b14f47503033bc2c85a259a968d94.png)
[paper reading] ckan: collaborative knowledge aware autonomous network for adviser systems
随机推荐
【Vite】1371- 手把手开发 Vite 插件
5G NR系统架构
Detailed explanation of the use of staticlayout
Usage differences between isempty and isblank
【tcp】服务器上tcp连接状态json形式输出
Singleton mode encapsulates activity management class
SAP ui5 objectpagelayout control usage sharing
SLAM 01.人类识别环境&路径的模型建立
AtCoder Beginner Contest 258「ABCDEFG」
请问大佬们 有遇到过flink cdc mongdb 执行flinksql 遇到这样的问题的么?
Workmanager learning 1
ModuleNotFoundError: No module named ‘scrapy‘ 终极解决方式
Golang应用专题 - channel
[论文阅读] CKAN: Collaborative Knowledge-aware Atentive Network for Recommender Systems
Completion report of communication software development and Application
How to plan the career of a programmer?
vscode的快捷键
DOM//
"Everyday Mathematics" serial 58: February 27
微信核酸检测预约小程序系统毕业设计毕设(7)中期检查报告