问题描述:
使用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这类组件


麦兜兜
15 声望3 粉丝

一个前端