写给小白的教程之WebComponent(1)

简介: 写给小白的教程之WebComponent(1)

网络异常,图片无法展示
|

1、为啥会有这一篇 ?

前两天有个同学问我,然后组内同学也即将分享相关实践内容,此处 在他之前发出(早一天发布的发布会),good!

2、是何物?

组件化是前端非常重要的一块内容,现在流行的 React 和 Vue 都是组件框架。

谷歌 Chrome 一直在推动浏览器的原生组件,即 Web Components API。相比第三方框架,原生组件简单直接,不用加载任何外部模块,代码量小。当前发展较为成熟,在很多项目中被使用

广受好评!

3、基本概念早知道

Web Components主要由三项技术组成,分别为

  • Custom elements(自定义元素)
  • Shadow DOM(影子DOM)
  • HTML templates(HTML模板)
  • 自定义元素实例
customElements.define(
'test-custom',   // name 
class TestCustom extends HTMLParagraphElement {   // 这个类定义功能
  constructor() {
    super();
    // 功能代码
    ...
  }
}, { extends: 'p' }); // 继承自哪个元素 此处 p
复制代码
  • 影子 DOM

Shadow DOM 可将隐藏的 DOM挂到一个元素上:且 shadow root 节点为起始根节点,在这个根节点的下方,可以是任意元素,和普通的 DOM 元素一样

  • 如下图

网络异常,图片无法展示
|

  • 想将一个 Shadow DOM附加到 custom element 怎么做?
class Button extends HTMLElement {
  constructor() {
    super();
    let shadow = this.attachShadow({mode: 'open'}); // 挂到 构造函数上
  }
}
复制代码
  • 操作一下 也是 ok 的
class Button extends HTMLElement {
  constructor() {
    super();
    let shadow = this.attachShadow({mode: 'open'});
    let p = document.createElement('p');
    shadow.appendChild(p);
  }
}
复制代码
  • 我想添加样式 怎么办 ?
let mySelfStyle = document.createElement('style');
mySelfStyle.textContent = `
    .btn-container {
      position: relative;
    }
    .btn {
        // ...
    }
`
shadow.appendChild(mySelfStyle);
复制代码
  • good !
  • HTML模版
  • 类似于 html 结构 和 vue slot
<html>
    <template>
        <h1><slot name="title"></slot></h1>
        <p><slot name="description"></slot></p>
    </template>
</html>
复制代码

4、磨拳擦掌,怎么使用 ?

  1. 创建一个类或函数来指定 web 组件的功能,如果使用类,请使用 ECMAScript 2015 的类语法 (参阅类获取更多信息)。
  2. 使用 CustomElementRegistry.define() 方法注册您的新自定义元素,并向其传递要定义的元素名称、指定元素功能的类、以及可选的其所继承自的元素。
  3. 如果需要的话,使用Element.attachShadow() 方法将一个 shadow DOM 附加到自定义元素上。使用通常的 DOM 方法向 shadow DOM 中添加子元素、事件监听器等等。
  4. 如果需要的话,使用 <template> 和<slot> 定义一个 HTML 模板。再次使用常规 DOM 方法克隆模板并将其附加到您的 shadow DOM 中。
  5. 在页面任何位置使用自定义元素,就像使用HTML DIV一样(为例)

5、实现一个 Button

  • 上面那段话 请忘掉!!! , 我们 写给 Button 试试

1、创建一个类来指定 web 组件的功能

customElements.define('mark-button', Button);
复制代码

2、使用Element.attachShadow() 方法将一个 shadow DOM 附加到自定义元素上

const shadowRoot = this.attachShadow({ mode: 'open' });
    const btn = document.createlement('button');
    btn.appendChild(templateContent.cloneNode(true));
    btn.setAttribute('class', 'mark-button');
复制代码

3、使用 <template> 和<slot> 定义一个 HTML 模板

<template id="btn_tpl">
  <slot name="btn-content">button content  xxx</slot>
</template>
复制代码

4、使用

<mark-button type="primary"><span slot="btn-content" id="btn_show">button test1</span></mark-button>
<mark-button type="warning"><span slot="btn-content">button test2</span></mark-button>
<mark-button type="default"><span slot="btn-content">button test3</span></mark-button>
复制代码

5、添加点击事件

document.querySelector('#btn_show').addEventListener('click', () => {
    modal.setAttribute('visible', 'true');
}, false)
复制代码

6、效果

网络异常,图片无法展示
|

  • 完整代码
// index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Web Component</title>
  </head>
  <body style="padding: 60px">
    <h1>Web Component 马克付</h1>
    <h2>1. Button</h2>
    <mark-button type="primary"
      ><span slot="btn-content" id="btn_primary"
        >button test1</span
      ></mark-button
    >
    <mark-button type="warning"
      ><span slot="btn-content" id="btn_danger">button test2</span></mark-button
    >
    <mark-button type="default"
      ><span slot="btn-content">button test3</span></mark-button
    >
    <!-- template定义区 -->
    <template id="btn_tpl">
      <slot name="btn-content">button content xxx</slot>
    </template>
    <script src="components/button.js"></script>
    <script>
      document.querySelector('#btn_primary').addEventListener(
        'click',
        () => {
          alert('我是 btn_primary ,我被点击了')
        },
        false
      )
      document.querySelector('#btn_danger').addEventListener(
        'click',
        () => {
          alert('我是 btn_danger 我很危险')
        },
        false
      )
    </script>
  </body>
</html>
复制代码
// Button.js
class Button extends HTMLElement {
  constructor() {
    super();
    // 获取模板内容
    let template = document.getElementById('btn_tpl');
    let templateContent = template.content;
    const shadowRoot = this.attachShadow({ mode: 'open' });
    const btn = document.createElement('button');
    btn.appendChild(templateContent.cloneNode(true));
    btn.setAttribute('class', 'mark-button');
    // 定义类型  primary | warning | default
    const type = {
      'primary': '#06c',
      'warning': 'red',
      'default': '#f0f0f0'
    }
    const btnType = this.getAttribute('type') || 'default';
    const btnColor = btnType === 'default' ? 'pink' : '#fff';
    // 创建样式
    const style = document.createElement('style');
    // 为shadow Dom添加样式
    style.textContent = `
      .mark-button {
        position: relative;
        display: inline-block;
        padding:8px 20px;
        border-radius: 50px;
        margin-right: 3px;
        background-color: ${type[btnType]};
        color: ${btnColor};
        box-shadow: inset 0 5px 10px rgba(0,0,0, .3);
        cursor: pointer;
      }
    `
    shadowRoot.appendChild(style);
    shadowRoot.appendChild(btn);
  }
}
customElements.define('mark-button', Button);
复制代码

代码细节和代码仓库

  • 感谢 支持 点个 star 点个赞吧 ! 祝大家暴富!
相关文章
|
分布式计算 资源调度 Hadoop
Hadoop: 启动后发现没有DataNode
Hadoop: 启动后发现没有DataNode
1310 0
Hadoop: 启动后发现没有DataNode
|
应用服务中间件 nginx
【已解决】nginx 502 Bad Gateway 问题排查
nginx 502 Bad Gateway 问题排查
16673 0
【已解决】nginx 502 Bad Gateway 问题排查
|
2月前
|
人工智能 移动开发 自然语言处理
阿里云秒悟(Meoo)全介绍:产品功能、应用场景、 9.9元1个月活动介绍
本文介绍了阿里云推出的秒悟(Meoo)云端极速AI应用创作平台,它聚合通义千问等四大主流大模型形成智能调度矩阵,用户仅需通过自然语言描述需求,即可在3-5分钟内生成包含前端页面、后端逻辑、数据库配置的完整应用,实现一键部署上线。平台推出免费体验版、Pro版、Max版三档梯度订阅,当前新用户可享Pro版低至9.9元/月的限时特惠,还能领取10000积分新人礼包。
|
10月前
|
人工智能 自然语言处理 安全
Serverless AI 原生架构破局「三高」困境
在 AI 大模型浪潮席卷全球的今天,企业纷纷加速拥抱 AI,推动智能客服、内容生成、流程自动化等场景快速落地。然而,许多企业在实践中却遭遇了“三高困境”——成本高、复杂度高、风险高。Serverless AI 原生架构不仅是技术演进,更是企业智能化转型的关键基础设施。它让开发者聚焦业务逻辑,让企业告别“基建焦虑”,让 AI 真正“飞入寻常百姓家”。
|
10月前
|
监控 安全 Linux
Rootkit检测利器rkhunter详解:原理、实践与渗透测试应用
rkhunter是一款开源Linux系统入侵检测工具,专用于检测Rootkit、后门及恶意软件。它通过MD5校验、文件权限检查、隐藏文件扫描、端口监听分析等多维度机制,识别系统异常。支持命令行交互与自动化扫描,可集成至安全巡检流程。广泛应用于渗透测试的后渗透阶段,辅助发现持久化威胁,是系统安全评估的重要利器。
1388 5
|
存储 人工智能 PyTorch
【AI系统】模型转换流程
本文详细介绍了AI模型在不同框架间的转换方法,包括直接转换和规范式转换两种方式。直接转换涉及从源框架直接生成目标框架的模型文件,而规范式转换则通过一个中间标准格式(如ONNX)作为桥梁,实现模型的跨框架迁移。文中还提供了具体的转换流程和技术细节,以及模型转换工具的概览,帮助用户解决训练环境与部署环境不匹配的问题。
940 5
【AI系统】模型转换流程
|
人工智能 弹性计算 监控
分布式大模型训练的性能建模与调优
阿里云智能集团弹性计算高级技术专家林立翔分享了分布式大模型训练的性能建模与调优。内容涵盖四大方面:1) 大模型对AI基础设施的性能挑战,强调规模增大带来的显存和算力需求;2) 大模型训练的性能分析和建模,介绍TOP-DOWN和bottom-up方法论及工具;3) 基于建模分析的性能优化,通过案例展示显存预估和流水线失衡优化;4) 宣传阿里云AI基础设施,提供高效算力集群、网络及软件支持,助力大模型训练与推理。
|
自然语言处理 数据安全/隐私保护 UED
如何选择适合的域名:关键步骤与策略
在数字化时代,域名不仅是网站的身份标识,更是品牌在线形象的重要组成部分。本文将指导您如何选择一个恰当、易于记忆且富有意义的域名,从明确目标与定位、选择合适的域名类型与后缀、考虑长度与可读性、检查可用性与合法性、评估SEO价值、考虑未来扩展、购买与注册到监测与维护,全方位帮助您打造优质域名。
1162 4
|
XML Java 数据格式
BeanFactory 和 ApplicationContext 的区别
【10月更文挑战第24天】在 Spring 框架中,`BeanFactory` 和 `ApplicationContext` 是两个核心的容器接口。`BeanFactory` 提供基本的 Bean 管理功能,支持延迟加载,适用于轻量级应用和资源受限环境。`ApplicationContext` 则在 `BeanFactory` 基础上扩展了丰富的企业级功能,如国际化、事件处理和资源管理,适用于企业级和 Web 应用开发。两者各有特点,需根据具体需求选择使用。
525 2
|
监控 安全 网络安全
深入理解VRF在网络通信中的角色与应用
【8月更文挑战第24天】
1517 0

热门文章

最新文章