目录
WebComponent 介绍js隔离问题解决方法一用 Proxy 代理方法二 用快照样式隔离问题方法一 样式增加不同前缀方法二 ShadawDom元素隔离WebComponent 介绍
微前端框架中,js隔离、样式隔离、元素隔离是必须解决的三个问题,下面我们就来分别说说这三个问题是什么?怎么解决?
涉及的核心点是 Proxy,WebComponent,shadowDOM
WebComponent 不在这三个问题中,但是我们做个简单介绍
(资料图片)
浏览器默认的标签有 div,a,p等等,浏览器是会自动识别,并且有默认的事件和样式。
浏览器相对于提供了WebComponent,我们可以自定义Html标签,注意规定自定义标签需要包含横线,如
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")
元素隔离
元素隔离是 基座应用和子应用都有一个元素
,此时子应用通过document.querySelector("#root"),因为js隔离已经做了代理,此时document.querySelector只是子应用本身了以上就是微前端之 js隔离 样式隔离 元素隔离问题详解的详细内容,更多关于微前端js 样式 元素隔离的资料请关注脚本之家其它相关文章!
X 关闭
X 关闭
- 1联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 2亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 3现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 4如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 5AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 6转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 7充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 8好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 9名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 10亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战