微前端之 js隔离 样式隔离 元素隔离问题详解

目录
  • WebComponent 介绍
  • js隔离
    • 问题
    • 解决
      • 方法一用 Proxy 代理
      • 方法二 用快照
  • 样式隔离
    • 问题
      • 方法一 样式增加不同前缀
      • 方法二 ShadawDom
  • 元素隔离

WebComponent 介绍

微前端框架中,js隔离、样式隔离、元素隔离是必须解决的三个问题,下面我们就来分别说说这三个问题是什么?怎么解决?

涉及的核心点是 Proxy,WebComponent,shadowDOM

WebComponent 不在这三个问题中,但是我们做个简单介绍

浏览器默认的标签有 div,a,p等等,浏览器是会自动识别,并且有默认的事件和样式。

浏览器相对于提供了WebComponent,我们可以自定义Html标签,注意规定自定义标签需要包含横线,如<user-card>,父类都是HTMLElement

attachShadow 是大多数标签都支持的,比如 div,p,selection,但是a,ul,li等不支持,如果执行attachShadow,那么组件的html结构会挂在shadowRoot下,否则直接挂着组件下。

用法

class UserCard extends HTMLElement {
  static get observedAttributes() {return ['name', 'url']; }
  constructor() {
    super();
    // 可以创Shadom,通过this.shadowRoot获取
    // this.attachShadow({ mode: 'open' })
  }
  connectedCallback (){
      console.log('钩子,元素append到ducument触发')
  }
  disconnectedCallback (){
      console.log('钩子,元素从document删除触发')
  }
  // 只有observedAttributes 中监听的属性name,url变化会触发下面回调
  attributeChangedCallback (attr, oldVal, newVal){
      console.log('钩子,元素属性改变时触发')
  }
}
window.customElements.define('user-card', UserCard);

更新细节查看 web自定义元素

js隔离

问题

主要是很对全局变量window

  • 情况1:都对全局变量赋值

应用A,写 window.r = 1;

然后有应用B,又写 window.r = 2,这就乱套了

  • 情况2:都设置事件

应用A,window.addEventListener('click',()=>console.log('A'));

应用B,window.addEventListener('click',()=>console.log('B'));

这就乱套了

解决

对应全局对象,各个应该要独立,怎么实现呢,有两种方法

方法一用 Proxy 代理

es2015 Reflect属于一个静态类或者设置属性等用法

const rawWindow = window
const proxyWindow = new Proxy({},{
    get: (target, key): unknown => {
        // 原 target 上有就返回,否则返回 rawWindow 属性
        return Reflect.has(target, key) ? Reflect.get(target, key) : Reflect.get(rawWindow, key)
    },
    set: (target, key, value): boolean => {
        if(!Object.prototype.hasOwnProperty.call(target, key) && Object.prototype.hasOwnProperty.call(rawWindow, key)){
            const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key)
            const { configurable, enumerable, writable, set } = descriptor!
            // set value because it can be set
            rawDefineProperty(target, key, {
              value,
              configurable,
              enumerable,
              writable: writable ?? !!set,
            })
        } else {
            Reflect.set(target, key, value)
        }
    }
})

将 window.r = 1 和 window.addEventListener('click',()=>console.log('A')) 包括到自执行函数里面

A和B互不干扰

;(function(window){
    window.r = 1
    window.addEventListener('click',()=>console.log('A'))
})(proxyWindowA)
;(function(window){
    window.r = 2
    window.addEventListener('click',()=>console.log('B'))
})(proxyWindowB)

方法二 用快照

快照隔离有个前提条件是,当前还有一个应用显示,不能出现多个应用并存显示在界面上,应用A,B切换时,比如当前应用是A,现在要切入到应用B

  • 暂存起来应用A的全局变量和事件
  • 恢复全局变量和事件到应用A之前
  • 检查之前是否保持有应用B的全局变量和事件,如果有,则载入

样式隔离

问题

同理,各个应用之前可能相互设置标签样式,会相互影响,或者影响全局样式,比如应用A给body设置样式,应用B也给body设置样式

方法一 样式增加不同前缀

每个应用通过前缀独立区分开,京东micro-app默认是采用的这个策略,唯一注意的一个小点是,基座样式会影响子应用的样式,所以需要注意基座中不要写太多样式

方法二 ShadawDom

大多数Html标签都有 attachShadow() 方法给指定的元素挂载一个 Shadow DOM。参数是open或closed

ShadawDom 样式绝对隔离,不用加前缀,如下图

用法

//open 是外界可以访问到Element.shadowRoot再访问到内部元素,closed就是完全不能访问内部元素
var shadowroot = element.attachShadow('open|closed')

元素隔离

元素隔离是 基座应用和子应用都有一个元素<div id='root'></div>,此时子应用通过document.querySelector('#root'),因为js隔离已经做了代理,此时document.querySelector只是子应用本身了

以上就是微前端之 js隔离 样式隔离 元素隔离问题详解的详细内容,更多关于微前端js 样式 元素隔离的资料请关注我们其它相关文章!

(0)

相关推荐

  • JS微前端MicroApp基础使用

    目录 1. 介绍 2. 主应用 2.1 路由配置和基础页面 2.2 全局生命周期配置 2.3 主应用插件系统 3. 子应用 3.1 Webpack + Vue 子应用 3.2 Webpack + React 子应用 4. 应用路由配置说明 4.1 主应用路由 4.2 子应用路由 1. 介绍 MicroApp 是“京东零售”团队在2021年7月正式发布的一个微前端框架,并且抛弃了 Single SPA 的实现理念,基于 CustomElement 和 ShadowDom 来实现. MicroAPP

  • 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP详解

    前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第4篇,接口隔离原则ISP(The Interface Segregation Principle). 英文原文:http://freshbrewedcode.com/derekgreer/2012/01/08/solid-javascript-the-interface-segregation-principle/ 注:这篇文章作者写得比较绕口,所以大叔理解得也比较郁闷,凑合着看吧,别深陷进去了 接口隔离原则的描述

  • 详解angularjs中的隔离作用域理解以及绑定策略

    我们首先看下面的例子: <!doctype html> <html ng-app="MyModule"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel

  • 教你如何通过JavaScript读取元素的样式

    目录 一.getComputedStyle() 1.getComputedStyle()是window的方法,可以获取元素当前的样式 2.两个参数 3.代码实例 4.浏览器效果 二.定义一个方法获取元素信息 1.代码实例 2.浏览器显示 三.clientWidth和clientHeight 1.这两个元素是获取元素的宽度和高度,不带px 2.这两个元素是只读的,不可修改 3.代码实例 4.浏览器展示 四.offsetWidth和offsetHeight 1.获取元素的整个的宽度和高度,包括内容区

  • Javascript 动态样式控制方法

    目录 方法一:使用style属性来设置 方法二:定义好类选择器的样式 方法一:使用style属性来设置 使用style属性来设置 html代码:     <div id="div1">         div     </div> Javascript代码: var div1 = document.getElementById("div1");         div1.onclick = function () {            

  • 原生JS与JQ获取元素的区别详解

    这篇文章主要介绍了原生JS与JQ获取元素的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 刚学JQ不久,有时候可能会把JS和JQ获取元素的方式搞错,接下来获取属性方法什么的就一发不可收拾了,现在把两者获取获取元素的代码整理下. 一.原生JS获取元素. 1.常用的三种方式获取元素对象(将指定的元素封装成DOM对象): (1)通过元素ID获取:document.getElementById(),示例如下: 我们在控制台输出,结果如下: 可以

  • 微前端之 js隔离 样式隔离 元素隔离问题详解

    目录 WebComponent 介绍 js隔离 问题 解决 方法一用 Proxy 代理 方法二 用快照 样式隔离 问题 方法一 样式增加不同前缀 方法二 ShadawDom 元素隔离 WebComponent 介绍 微前端框架中,js隔离.样式隔离.元素隔离是必须解决的三个问题,下面我们就来分别说说这三个问题是什么?怎么解决? 涉及的核心点是 Proxy,WebComponent,shadowDOM WebComponent 不在这三个问题中,但是我们做个简单介绍 浏览器默认的标签有 div,a

  • 前端JS图片懒加载原理方案详解

    目录 背景 原理 方案 方案一:img的loading属性设为“lazy” 使用方法 优点 兼容性 缺点 方案二:通过offsetTop来计算是否在可视区域内 优化 优点 缺点 方案三:通过getBoundingClientRect来计算是否在可视区域内 方案四:使用IntersectionObserver来判断是否在可视区域内 兼容性 优点 缺点 问题 布局抖动 响应式图片 SEO不友好 插件 背景 懒加载经常出现在前端面试中,是前端性能优化的常用技巧.懒加载也叫延迟加载,把非关键资源先不加载

  • 前端JavaScript多数元素的算法详解

    目录 题目:多数元素 方法一:map 实现 方法二:排序 题目:多数元素 给定一个大小为 n 的数组 nums ,返回其中的多数元素.多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: nums = [3,2,3]输出: 3 示例 2: 输入: nums = [2,2,1,1,1,2,2]输出: 2 提示: n == nums.length 1 <= n <= 5 * 104 -109 <= nums

  • JS前端同源策略和跨域及防抖节流详解

    目录 引言 jQuery中JSONP的实现 防抖[重要] 缓存搜索的列表 1 定义全局缓存对象 2:将搜索结果存储到缓存对象中 3优先从缓存中获取搜索列表 节流[重点] 防抖和节流的区别 引言 协议,域名,端口相同,就具有相同的源 同源策略:浏览器提供的一个安全策略 跨域的出现原因:浏览器的同源策略不允许非同源的URL之间进行资源的交互 解决跨域由两种方式:JSONP, CORS JSONP: 只支持GET请求 通过script标签的src属性,请求跨域的数据接口,并通过函数调用的形式,接收跨域

  • 基于js中this和event 的区别(详解)

    今天在看javascript入门经典-事件一章中看到了 this 和 event 两种传参形式.因为作为一个初级的前端开发人员平时只用过 this传参,so很想弄清楚,this和event的区别是什么,什么情况下用什么比较合适. onclick = changeImg(this)       vs     onclick = changeImg(event) <img src='usa.gif' onclick="changeImg(event)" /> <scrip

  • 基于 D3.js 绘制动态进度条的实例详解

    D3 是什么 D3 的全称是(Data-Driven Documents),顾名思义可以知道是一个被数据驱动的文档.听名字有点抽象,说简单一点,其实就是一个 JavaScript 的函数库,使用它主要是用来做数据可视化的.如果你不知道什么是 JavaScript ,请先学习一下 JavaScript,推荐阮一峰老师的教程. JavaScript 文件的后缀名通常为 .js,故 D3 也常使用 D3.js 称呼.D3 提供了各种简单易用的函数,大大简化了 JavaScript 操作数据的难度.由于

  • Vue.js 中的 v-cloak 指令及使用详解

    先来看下vue.js 中的v-cloak 指令 可以使用 v-cloak 指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除. 当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码.我们可以使用 v-cloak 指令来解决这一问题. html: <div id="app"> {{context}} </div> js: <script> var app = new

  • Vue.js 中的 v-show 指令及用法详解

    1 用法 v-show 指令通过改变元素的 css 属性(display)来决定元素是显示还是隐藏. html: <div id="app"> <p v-show="type==='科技'">大数据之下的锦鲤:为什么你的微博总抽不到奖</p> </div> js: <script> var app = new Vue({ el: '#app', data: { type:'技术' } }); </sc

  • 对layui中表单元素的使用详解

    首先不管是单选框还是复选框或者是下拉框,都要在你写的标签外面套一层div或者是form标签,如: <div class="layui-input-block"> <input type="radio" name="sex" value="0" title="男"> </div>,class属性是固定写法. 这样写好了以后,你如果是写在静态页面,这样式可以看见效果,如果写在

随机推荐