问题描述:
使用qiankun做为微前端时,主应用是vue3+elementPlus,子应用是vue2+element。这时主应用的elementPlus的样式会作用到子应用element,带来样式污染。
什么会出现这个问题:
1、qiankun不是提供样式沙箱隔离吗?为什么还会出现这种问题
qiankun提供两种沙箱隔离配置
// 启动 qiankun
start({
sandbox : { strictStyleIsolation: true } // 严格隔离
// sandbox : { experimentalStyleIsolation: true } 试验性隔离
});
strictStyleIsolation的原理是使用shadow dom。每个子应用的根组件都会被包裹在一个 Shadow DOM 中。
用这个配置,样式的确隔离了。但是子应用挂载在body下的元素会定位出现问题(比如下拉框、弹出框等)。❌
experimentalStyleIsolation的原理类似scoped。为子应用的样式增加唯一标识 div[data-qiankun="sub-app”]
会发现子应用还是能加载到主应用相同的样式,比如.el-button,导致样式错误 ❌
如何解决:
1、elementPlus提供了自定义命名空间,用在主应用的根组件上
<!-- App.vue -->
<template>
<el-config-provider namespace="main">
<!-- ... -->
</el-config-provider>
</template>
2、然后把样式的$namespace这个动态值赋值,配置样式预处理器并且动态引入elementPlus
// styles/element/index.scss
// we can add this to custom namespace, default is 'el'
@forward 'element-plus/theme-chalk/src/mixins/config.scss' with (
$namespace: 'main'
);
// 在vue-config-js里引入这个文件
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const {
ElementPlusResolver
} = require('unplugin-vue-components/resolvers’)
css: {
loaderOptions: {
scss: {
additionalData: `@use "~@/styles/element.scss" as *;`
},
}
},
configureWebpack: {
plugins: [
AutoImport({
resolvers:
[ElementPlusResolver({
importStyle: 'sass' // 指示element-plus使用预处理样式
})],
}),
Components({
resolvers: [ElementPlusResolver({
importStyle: 'sass' // 指示element-plus使用预处理样式
})],
})
]
},
3、运用这个自定义命名空间这个功能后,发现还是存在问题。挂载在body下的组件,例如Message,dom上的类名并没有被转换(2.2.19bug)。并且elementPlus只是把样式复制了一份命名空间为main的样式,原来的el的样式表还是存在的,子应用还是被影响了。
4、编写cssloader
把主应用命名为el-的样式和--el的都替换为命名空间main,相当于删除原来el的样式表,除开message这类组件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。