微服务实践和总结

news2024/11/14 3:24:26

H5原生组件web Component

Web Component 是一种用于构建可复用用户界面组件的技术,开发者可以创建自定义的 HTML 标签,并将其封装为包含逻辑和样式的独立组件,从而在任何 Web 应用中重复使用。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>web Component原生组件</title>
  </head>
  <body>
    <m-button type="primary">webComponent</m-button>

    <template id="m-btn">
      <button class="m-button">
        <slot>Default</slot>
      </button>
    </template>

    <template id="m-btn">
      <style type="text/css">
        .m-button {
          width: 100%;
          border: 1px solid #ebebeb;
        }
      </style>

      <div class="m-collapse">
        <slot></slot>
      </div>
    </template>

    <script type="text/javascript">
      class MButton extends HTMLElement {
        constructor() {
          super()

          let btnTmpl = document.getElementById('m-btn') // 定义模板并获取模板

          let shadow = this.attachShadow({ mode: 'open' }) // 配置 devtools 是否可查看 DOM 结构,open / close
          let cBtnTmpl = btnTmpl.content.cloneNode(true) // copy 模板便于重用

          cBtnTmpl.querySelector('.m-button').addEventListener('click', this.onClick)

          shadow.appendChild(cBtnTmpl) // 模板挂载 Shadow DOM
        }

        static get observedAttributes() {
          return ['type'] // 监控 type 属性是否改变
        }

        connectedCallback() {
          // 组件首次挂载时调用
        }

        attributeChangedCallback(key, oldValue, newValue) {
          // 组件更新时调用,key 为属性名,oldValue, newValue 为属性值
        }

        disconnectedCallback() {
          // 组件移除时调用
        }
      }
    </script>
  </body>
</html>

Shadow DOM

Shadow DOM 是 DOM nodes 的附属树。这种 Shadow DOM 子树可以与某宿主元素相关联,但并不作为该元素的普通子节点,而是会形成其自有的作用域;Shadow DOM 中的根及其子节点也不可见。

  • 不使用Shadow DOM
    在这里插入图片描述
<!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Web Components</title>
    <style>
        h1 {
            font-size: 20px;
            color: yellow;
        } 
    </style>
    </head>
    <body>
    <div></div>
    <hello-world></hello-world>
    <h1>Hello World! 外部</h1>
    <script type="module">
     class HelloWorld extends HTMLElement {
            constructor() {
                super();
                // 关闭 shadow DOM
                // this.attachShadow({ mode: 'open' });

                const d = document.createElement('div');
                const s = document.createElement('style');
                s.innerHTML = `h1 {
                            display: block;
                            padding: 10px;
                            background-color: #eee;
                        }`
                d.innerHTML = `
                    <h1>Hello World! 自定义组件内部</h1>
                `;

                this.appendChild(s);
                this.appendChild(d);
            }

            tag = 'hello-world'

            say(something) {
                console.log(`hello world, I want to say ${this.tag} ${something}`)
            }
        }

        window.customElements.define('hello-world', HelloWorld);
        const hw = document.querySelector('hello-world'); 
        hw.say('good');
 </script>
 </body>
 </html>
  • 使用 Shadow DOM
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Web Components</title>
<style>
 h1 {
    font-size: 20px;
    color: yellow;
} </style>
</head>
<body>
    <div></div>
    <hello-world></hello-world><h1>Hello World! 外部</h1>
    <script type="module"> class HelloWorld extends HTMLElement {
            constructor() {
                super();
                this.attachShadow({ mode: 'open' });
                this.shadowRoot.innerHTML = `
                    <style>
                        h1 {
                            font-size: 30px;
                            display: block;
                            padding: 10px;
                            background-color: #eee;
                        }
                    </style><h1>Hello World! 自定义组件内部</h1>
                `;
            }

            tag = 'hello-world'

            say(something) {
                console.log(`hello world, I want to say ${this.tag} ${something}`)
            }
        }

        window.customElements.define('hello-world', HelloWorld);
        const hw = document.querySelector('hello-world'); 
        hw.say('good'); 
        </script>
</body>
</html>

HTML templates 和 slot

元素允许开发者在 HTML 中定义一个模板,其中可以包含任意的 HTML 结构、文本和变量占位符。此元素及其内容不会在 DOM 中呈现,但仍可使用 JavaScript 去引用它。

微前端

回顾微前端的历史,最早的时候我们是利用 iframe 嵌入一个网页,这就是微前端的雏形。虽然接入时方便快捷,但它也存在一系列缺点,如:

  • 路由状态丢失,刷新一下,iframe 的 url 状态就丢失了
  • dom 割裂严重,弹窗只能在 iframe 内部展示,无法覆盖全局
  • 通信非常困难,只能通过 postmessage 传递序列化的消息
  • 白屏时间太长,对于有性能要求的应用来说无法接受

微前端的特点

路由隔离、js隔离、css隔离、预加载机制、通信机制、多微应用激活

import microApp from '@micro-zoe/micro-app';
microApp.start();export function MyPage () {
 return (<div>    
      <h1>子应用</h1>  
       <micro-app 
           name='app1' // name(必传):应用名称  
           url='http://localhost:3000/' // url(必传):应用地址,会被自动补全为http://localhost:3000/index.html       
           baseroute='/my-page' // baseroute(可选):基座应用分配给子应用的基础路由,就是上面的 `/my-page`
        ></micro-app>    
   </div>  )}

js隔离(沙箱)

export class SnapShot { 
proxy: Window & typeof globalThis 
constructor () { 
    this.proxy = window 
} 
// 沙箱激活 
active () { 
    // 创建一个沙箱快照 
    this.snapshot = new Map() 
    // 遍历全局环境 
    for (const key in window) { 
        this.snapshot[key] = window[key] 
    } 
} 
// 沙箱销毁 
inactive () { 
    for (const key in window) { 
         if (window[key] !== this.snapshot[key]) { 
             // 还原操作 
             window[key] = this.snapshot[key] 
         } 
    } }
 }

microApp 使用过程中碰到的问题

  • webpack-dev-server中添加headers解决父应用引入子应用不同域名跨域问题
  headers: {
    'Access-Control-Allow-Origin': '*',
  }

原理解析

当调用 microApp.start() 后,会注册一个名为 micro-app 的自定义 webComponent 标签。我们可以从 中拿到子应用的线上入口地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1950383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python | Leetcode Python题解之第283题移动零

题目&#xff1a; 题解&#xff1a; class Solution:def moveZeroes(self, nums: List[int]) -> None:n len(nums)left right 0while right < n:if nums[right] ! 0:nums[left], nums[right] nums[right], nums[left]left 1right 1

springboot游戏化教育平台-计算机毕业设计源码92424

游戏化教育平台设计与实现 摘 要 游戏化教育平台是一种融合了游戏元素和教育内容的创新型教育工具&#xff0c;旨在提升学习者的学习兴趣和参与度。本论文基于SpringBoot框架&#xff0c;设计并实现了一款游戏化教育平台。该平台包括用户和管理员两大功能模块。对于用户功能而…

Linux开启coredump

在Linux系统中&#xff0c;C/C程序崩溃是常见的问题之一。Coredump是指当一个程序崩溃时&#xff0c;系统把程序运行时的内存数据以二进制文件的形式保存下来&#xff0c;以便程序开发者进行崩溃分析。本文将介绍如何开启并配置Coredump 1、查看并配置coredump 在Linux系统中…

mac M1安装Roop教程及所遇到的问题

1.安装miniconda&#xff0c;下载地址&#xff1a; 按 Python 版本划分的最新 Miniconda 安装程序链接&#xff1a;https://docs.anaconda.com/miniconda/miniconda-other-installer-links/ 下载后直接默认安装即可。 我用的是&#xff1a;Python3.10对应的Miniconda 2.下载…

在 ArchLinux 上编译运行 axmol 引擎

本文将在 Windows 10 上安装 Arch WSL 中编译 axmol 请确保 WSL2 已正确安装 1. 在微软应用商店安装 ArchLinux 2. 打开 Arch&#xff0c;按照提示输入用户名和密码&#xff0c;尽量简单 3. 配置清华源&#xff0c;速度快的起飞&#xff0c;否则&#xff0c;各种包会安装失败…

C++必修:模拟实现STL之string

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 为了让我们更加深入理解string&#xff0c;接下来我们将模拟实现一个简易版的stri…

力扣高频SQL 50题(基础版)第十七题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第十七题1075. 项目员工 I题目说明思路分析实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第十七题 1075. 项目员工 I 题目说明 项目表 Project&#xff1a; ----------------…

四、GD32 MCU 常见外设介绍 (2) GPIO 模块介绍

2.GPIO 模块介绍 GPIO的全称为通用输入输出口&#xff0c;是很多外设能够正常工作的必要条件。除了一些特定功能的引脚(如电源脚)外&#xff0c;MCU上其他的引脚都可以当做GPIO来使用。本章&#xff0c;我们将对GPIO进行简单介绍&#xff0c;并通过一个“流水灯”的实验来熟悉…

力扣刷题-图论-岛屿类问题-集合实现(c++实现)

我的老师&#xff1a;力扣链接这道题题解中最高赞的回答nettee&#xff0c;从这篇题解中我学到了dfs框架以及解决思路&#xff0c;并独立完成了该题解里的几道习题本人刷题的习惯是学会一个板子&#xff0c;然后之后的同类题都机械的用这个板子去做&#xff0c;最好不做创新&am…

广州某展厅门牌创新案例:1*2 OLED柔性屏的精致应用

在广州这座繁华都市的心脏地带&#xff0c;一座现代感十足的展厅悄然矗立&#xff0c;其独特的门牌设计成为了过往行人目光的焦点。这座展厅的门牌采用了前沿的1*2 OLED柔性屏技术&#xff0c;不仅展现了科技与艺术的完美融合&#xff0c;更彰显了展厅的高端定位与创新精神。 项…

容器 string 的模拟实现

容器 string 的模拟实现 开篇解释代码实现&#xff1a;myString.h 头文件myString.cpp 实现文件 模拟实现 string 能对 STL 有更深刻的认识&#xff0c;底层了解越丰富&#xff0c;使用起来越顺手 接下来我会以 .h 头文件以及其 .cpp 的实现文件展示其大致模拟&#xff0c;这只…

【代码】Python3|Scrapy框架初探(汽车之家大连市二手车车辆数据爬取、清洗与可视化)

本篇主要是整个项目的介绍&#xff0c;没提到太多琐碎的技术细节&#xff0c;以后有空的话会整理一下 Scrapy 和原生爬虫的差异&#xff0c;还有它坑人的一些地方&#xff0c;单发出来。 开源地址&#xff1a;https://github.com/shandianchengzi/car_home_spider 使用说明&a…

学习日记:数据类型2

目录 1.转义字符 2.隐式类型转换 2.1 强制类型转换 2.2 不同类型间赋值 3.运算符 表达式 3.1 算术运算符 3.2 算术运算优先级 3.3 赋值运算 3.3.1 不同类型间混合赋值 3.4 逗号运算 4.生成随机数 5. 每日一练 1.转义字符 \n 表示换行 \t …

Vue3可媲美Element Plus Tree组件实战之移除节点

Element Plus Tree自定义节点内容示例中介绍了移除节点的用法&#xff0c;个人觉得作为提供给用户API&#xff0c;应该遵循迪米特法则&#xff0c;把功能实现的细节封装在组件内部&#xff0c;而提供给用户最简单的操作方式&#xff0c;同时在此基础上支持用户的扩展。 因此&a…

ITK-中值滤波

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 中值滤波原理 中值滤波是一种常用的非线性滤波技术&#xff0c;用于去除图像中的噪声&#xff0c;特别是椒盐噪声和脉冲噪声。它…

MM 7 -采购- 询报价

思维导图 说明 sap提供了 询价 报价和比价的功能。 不建议在sap管理。一般引导不在sap管理。 流程&#xff1a; 操作 询价 ME41 报价ME47 比价ME49 拒绝 对于不符合条件的报价进行拒绝 生成信息记录 后台表 Ekko ekpo 。采购凭证类别&#xff1a;A

csa笔记6-网络管理命令

nmcli命令 字符终端&#xff0c;可以立即生效且重启系统后配置也不会丢失 nmtui命令 可视终端&#xff0c;立即生效&#xff0c;重启有效 network.service 管理网络 RHEL 7 以前&#xff1a;使用network.service管理网络 RHEL 7&#xff1a;使用network.service和Netwo…

Docker(十一)-Docker运行nginx1.10容器实例

1.下载镜像 docker pull nginx:1.102.直接启动实例(目的&#xff1a;复制出配置文件) 2.1启动实例 docker run -d -p 80:80 --namenginx1.10 nginx:1.102.2将容器内文件拷贝到本地目录 docker cp nginx1.10:/etc/nginx /software/nginx/将/software/nginx/nginx目录改为/so…

07 JSP

文章目录 JSP1、JSP 概述2、JSP 脚本和缺点3、EL 表达式4、JSTL标签5、MVC模式和三层架构6、案例 JSP 1、JSP 概述 JSP&#xff08;全称&#xff1a;Java Server Pages&#xff09;&#xff1a;Java 服务端页面 &#xff08;1&#xff09;是一种动态的网页技术 &#xff08;2&…

11 逻辑运算符

逻辑运算符 and、or、not 常用来连接条件表达式构成更加复杂的条件表达式&#xff0c;并且 and 和 or 具有惰性求值或逻辑短路的特点&#xff0c;当连接多个表达式时只计算必须要计算的值。 运算符 and 和 or 并不一定会返回 True 或 False &#xff0c;而是得到最后一个被计算…