繁体   English   中英

在 shadow-root 内部注入 CSS styles 而不是 head 标签 | Vue.js & Webpack

[英]Inject CSS styles inside of the shadow-root instead of the head tag | Vue.js & Webpack

我正在使用 Vue.js 和vue-custom-element为网站制作一个可嵌入的小部件。 一切都很顺利,直到我遇到问题。

当我尝试使用 package 中的组件(带有 css)时。 例如像vue-number-input一样。 css 被注入到网页的头部,即使它应该被添加到影子根中。

正如您在此处看到的,您看到来自数字输入 package 的 css 被注入到头部内部,而其他样式则像应有的那样位于阴影根中。

据我所知,我更改了使应用程序在影子根中工作所需的所有设置。

这是我的vue.config.js 、我的main.js (我注册自定义元素的地方)和我的组件(我从包中导入组件的地方)。

有谁知道我怎么能做到这一点,或者这甚至可能吗?

如果库本身将 styles 嵌入到页面的头部,那么除了编写一些脚本在初始化后手动将其复制到 shadow dom 之外,您无能为力。 我在 Font Awesome 图标上遇到了同样的问题。 幸运的是,他们为此提供了解决方案。 https://github.com/FortAwesome/vue-fontawesome#web-components-with-vue-web-component-wrapper

在对实际上将我们的 styles 延迟加载到 shadow-root 中的解决方案进行了大量研究之后,我们没有找到。 我们采用了次优解决方案,即在第一次加载时加载所有 styles。

注意:这使它适用于 QA 和生产环境。 开发时,styles 仍然会加载到页面头部的内部。 所以你必须确保没有其他 styles 与此冲突。

这是我们实现这一目标的方式:

// vue.config.js

const webpack = require('webpack');

module.exports = {
  configureWebpack: {
    // ...
    plugins: [
      new webpack.optimize.LimitChunkCountPlugin({
        maxChunks: 1,
      }),
    ],
  },
  chainWebpack: (config) => {
    config.optimization.delete('splitChunks');
  },
};
// main.js

import createStyleLink from '@/helpers/createStyleLink';

// ...

const options = {};

// Enable shadow root for production build
if (process.env.NODE_ENV === 'production') {
  options.shadow = true;
  options.beforeCreateVueInstance = (root) => {
    const rootNode = root.el.getRootNode();
    if (rootNode instanceof ShadowRoot) {
      root.shadowRoot = rootNode;
    } else {
      root.shadowRoot = document.head;
    }
    // After deployment, this will create a style link and put it inside the shadow root. 
    // Preferably, you would use a CDN for this.
    createStyleLink(rootNode, `${process.env.VUE_APP_URL}/css/app.css`);
    return root;
  };
}

// ...

Vue.customElement('widget', App, options);
// createStyleLink.js

export default function (node, url) {
  const link = document.createElement('link');
  link.href = url;
  link.type = 'text/css';
  link.rel = 'stylesheet';
  node.appendChild(link);
}

我不会将此标记为解决方案,因为这更像是一种次优的解决方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM