120.乾坤css隔离机制
- 确保单实例场景子应用之间的样式隔离,但是无法确保主应用跟子应用、或者多实例场景的子应用样式隔离
start({sandbox : true})//沙箱隔离,
判断沙箱隔离的方法,发现直接设置sandbox=true是不行的,需要使用experimentalStyleIsolation
这个属性配置。
export function isEnableScopedCSS(sandbox: FrameworkConfiguration['sandbox']) {if (typeof sandbox !== 'object') {return false;}if (sandbox.strictStyleIsolation) {return false;}return !!sandbox.experimentalStyleIsolation;
}
{ strictStyleIsolation: true }
开启严格的样式隔离模式 ,shawod dom’
start({shadow:{ strictStyleIsolation: true }})
直观的可以看到,子应用的代码不是正常的dom,上面显示的shadow-root,先不管shadow-root是什么,接着往下看
experimentalStyleIsolation
给子应用加上自定义的data-xxx属性,相当于vue中我们通常使用的scoped,从生成的代码中可以看出来
在主应用中,通过配置sandbox
做到样式隔离
start({ sandbox: { strictStyleIsolation: true } });
在start得时候配置得参数,但是只有等到start函数里面 frameworkStartedDefer.resolve()
之后才能往下执行. registerMicroApps
只是准备好注册的应用配置信息,只有等调用了start方法之后,才会走registerApplication
相关逻辑,registerApplication
是single-spa
中的一个主要的方法,乾坤实现微应用也主要用的是single-spa
这个库
start 方法
export function start(opts: FrameworkConfiguration = {}) {frameworkConfiguration = { prefetch: true, singular: true, sandbox: true, ...opts };startSingleSpa({ urlRerouteOnly });started = true;//执行loadApp相关逻辑frameworkStartedDefer.resolve();
}
修改appid得代码是在single-spa中还是qiankun中得?->qiankun,在处理模板的时候使用shadow dom
实现的
loadApp中使用严格样式隔离的代码
export async function loadApp<T extends ObjectType>(app: LoadableApp<T>,configuration: FrameworkConfiguration = {},lifeCycles?: FrameworkLifeCycles<T>,
): Promise<ParcelConfigObjectGetter> {const strictStyleIsolation = typeof sandbox === 'object' && !!sandbox.strictStyleIsolation;let initialAppWrapperElement: HTMLElement | null = createElement(appContent,strictStyleIsolation,scopedCSS,appInstanceId,);
}
createElement方法相关代码,我们在start
方法中配置了strictStyleIsolation
严格样式模式,因此会走到strictStyleIsolation
判断相关逻辑里面,从这里面就可以看到创建shadow dom
相关代码
function createElement(appContent: string,strictStyleIsolation: boolean,scopedCSS: boolean,appInstanceId: string,
): HTMLElement {const containerElement = document.createElement('div');containerElement.innerHTML = appContent;// appContent always wrapped with a singular divconst appElement = containerElement.firstChild as HTMLElement; //绝对样式隔离相关代码if (strictStyleIsolation) {//使用shadow做样式隔离const { innerHTML } = appElement;appElement.innerHTML = '';let shadow: ShadowRoot;if (appElement.attachShadow) {shadow = appElement.attachShadow({ mode: 'open' });} else {// createShadowRoot was proposed in initial spec, which has then been deprecatedshadow = (appElement as any).createShadowRoot();}shadow.innerHTML = innerHTML;}
//...scopedCSS判断相关代码return appElement;
}
使用scopedCss
做到样式隔离
前面入口出的逻辑和shadow
大致相同,scopedCss代码也很好理解,就是先查找要添加的应用是否有相应的属性,没有的话给子应用容器添加一个属性。然后遍历每个style标签,在每个style标签代码前面增加属性选择符,通过属性选择符 样式来确保样式不被重写
if (scopedCSS) {const attr = appElement.getAttribute(css.QiankunCSSRewriteAttr);if (!attr) {//这边attr生成的属性:data-qiankun :vue2AppappElement.setAttribute(css.QiankunCSSRewriteAttr, appInstanceId);}const styleNodes = appElement.querySelectorAll('style') || [];forEach(styleNodes, (stylesheetElement: HTMLStyleElement) => {css.process(appElement!, stylesheetElement, appInstanceId);});}
css.process方法
export const process = (appWrapper: HTMLElement,stylesheetElement: HTMLStyleElement | HTMLLinkElement,appName: string,
): void => {// lazy singleton patternif (!processor) {processor = new ScopedCSS();}const mountDOM = appWrapper;if (!mountDOM) {return;}const tag = (mountDOM.tagName || '').toLowerCase();if (tag && stylesheetElement.tagName === 'STYLE') {//生成前缀const prefix = `${tag}[${QiankunCSSRewriteAttr}="${appName}"]`;processor.process(stylesheetElement, prefix);}
};
可以将标记结构,样式和行为隐藏起来,和页面上其他代码相隔离。
shadow dom的一个demo:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><style> h1 {color: red;} </style><body><h1>hello 这个主页中的内容</h1><div id="box"></div></body><script> window.onload = function () {let box = document.getElementById("box");//开启shadow dombox.attachShadow({ mode: "open" });let shadow = box.shadowRoot;var h1 = document.createElement("h1");h1.innerHTML = "world 这是shaow dom中的内容";var style = document.createElement("style");style.textContent = `h1{color:green}`;shadow.appendChild(style);shadow.appendChild(h1);}; </script>
</html>
最后
最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。
有需要的小伙伴,可以点击下方卡片领取,无偿分享
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcjejb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01