【问题标题】:Styling not applied to vue web component during development样式在开发期间未应用于 vue Web 组件
【发布时间】:2019-04-25 04:25:53
【问题描述】:

在开发 Vue web 组件时,style 并没有应用于 web 组件,而是添加到文档的 head 中。这意味着样式在 shadow DOM 中被忽略。这是我在 main.js 中包装 Web 组件的方式:

import Vue from 'vue';
import wrap from '@vue/web-component-wrapper';
import MyWebComponent from './components/MyWebComponent';

const WrappedElement = wrap(Vue, MyWebComponent);

window.customElements.define('my-web-component', WrappedElement);

同样,样式标签内的任何 CSS 规则都不会生效。

当我为生产构建时,样式被添加到网络组件中。我使用以下命令进行包装:

vue-cli-service build  --target wc --name my-web-component ./src/components/MyWebComponent.vue

有没有办法用vue-cli-service serve 实现同样的目标?

编辑:此处的示例回购:https://github.com/snirp/vue-web-component

edit2:我感觉我的问题与this issue 密切相关。我无法理解这些变通方法,我会重视更基本的解决方案。

【问题讨论】:

    标签: css vue.js vuejs2 web-component


    【解决方案1】:

    根据您链接的 GitHub 问题,solution 是设置shadowMode option in vue-loadervue-style-loadershadowMode 在 Vue CLI 项目中默认为 false,但我们可以在 vue.config.js 中调整它。

    首先,我们将inspect the Webpack config 确定要更改哪些加载器:

    # run at project root
    vue inspect
    

    command output 揭示了几个带有 shadowMode: false 的加载器配置:

    /* config.module.rule('css') */
    {
      test: /\.css$/,
      oneOf: [
        /* config.module.rule('css').oneOf('vue-modules') */
        {
          resourceQuery: /module/,
          use: [
            /* config.module.rule('css').oneOf('vue-modules').use('vue-style-loader') */
            {
              loader: 'vue-style-loader',
              options: {
                sourceMap: false,
                shadowMode: false  // <---
              }
            },
            /* ... */
          ]
        },
        /* ... */
    

    带有shadowMode: false 的 Webpack 加载器配置的完整列表:

    config.module.rule('vue').use('vue-loader')
    config.module.rule('css').oneOf('vue-modules').use('vue-style-loader')
    config.module.rule('css').oneOf('vue').use('vue-style-loader')
    config.module.rule('css').oneOf('normal-modules').use('vue-style-loader')
    config.module.rule('css').oneOf('normal').use('vue-style-loader')
    config.module.rule('postcss').oneOf('vue-modules').use('vue-style-loader')
    config.module.rule('postcss').oneOf('vue').use('vue-style-loader')
    config.module.rule('postcss').oneOf('normal-modules').use('vue-style-loader')
    config.module.rule('postcss').oneOf('normal').use('vue-style-loader')
    config.module.rule('scss').oneOf('vue-modules').use('vue-style-loader')
    config.module.rule('scss').oneOf('vue').use('vue-style-loader')
    config.module.rule('scss').oneOf('normal-modules').use('vue-style-loader')
    config.module.rule('scss').oneOf('normal').use('vue-style-loader')
    config.module.rule('sass').oneOf('vue-modules').use('vue-style-loader')
    config.module.rule('sass').oneOf('vue').use('vue-style-loader')
    config.module.rule('sass').oneOf('normal-modules').use('vue-style-loader')
    config.module.rule('sass').oneOf('normal').use('vue-style-loader')
    config.module.rule('less').oneOf('vue-modules').use('vue-style-loader')
    config.module.rule('less').oneOf('vue').use('vue-style-loader')
    config.module.rule('less').oneOf('normal-modules').use('vue-style-loader')
    config.module.rule('less').oneOf('normal').use('vue-style-loader')
    config.module.rule('stylus').oneOf('vue-modules').use('vue-style-loader')
    config.module.rule('stylus').oneOf('vue').use('vue-style-loader')
    config.module.rule('stylus').oneOf('normal-modules').use('vue-style-loader')
    config.module.rule('stylus').oneOf('normal').use('vue-style-loader')
    

    所以,我们可以用这个 sn-p 为vue.config.js 中的那些配置设置shadowMode: true

    function enableShadowCss(config) {
      const configs = [
        config.module.rule('vue').use('vue-loader'),
        config.module.rule('css').oneOf('vue-modules').use('vue-style-loader'),
        config.module.rule('css').oneOf('vue').use('vue-style-loader'),
        config.module.rule('css').oneOf('normal-modules').use('vue-style-loader'),
        config.module.rule('css').oneOf('normal').use('vue-style-loader'),
        config.module.rule('postcss').oneOf('vue-modules').use('vue-style-loader'),
        config.module.rule('postcss').oneOf('vue').use('vue-style-loader'),
        config.module.rule('postcss').oneOf('normal-modules').use('vue-style-loader'),
        config.module.rule('postcss').oneOf('normal').use('vue-style-loader'),
        config.module.rule('scss').oneOf('vue-modules').use('vue-style-loader'),
        config.module.rule('scss').oneOf('vue').use('vue-style-loader'),
        config.module.rule('scss').oneOf('normal-modules').use('vue-style-loader'),
        config.module.rule('scss').oneOf('normal').use('vue-style-loader'),
        config.module.rule('sass').oneOf('vue-modules').use('vue-style-loader'),
        config.module.rule('sass').oneOf('vue').use('vue-style-loader'),
        config.module.rule('sass').oneOf('normal-modules').use('vue-style-loader'),
        config.module.rule('sass').oneOf('normal').use('vue-style-loader'),
        config.module.rule('less').oneOf('vue-modules').use('vue-style-loader'),
        config.module.rule('less').oneOf('vue').use('vue-style-loader'),
        config.module.rule('less').oneOf('normal-modules').use('vue-style-loader'),
        config.module.rule('less').oneOf('normal').use('vue-style-loader'),
        config.module.rule('stylus').oneOf('vue-modules').use('vue-style-loader'),
        config.module.rule('stylus').oneOf('vue').use('vue-style-loader'),
        config.module.rule('stylus').oneOf('normal-modules').use('vue-style-loader'),
        config.module.rule('stylus').oneOf('normal').use('vue-style-loader'),
      ];
      configs.forEach(c => c.tap(options => {
        options.shadowMode = true;
        return options;
      }));
    }
    
    module.exports = {
      // https://cli.vuejs.org/guide/webpack.html#chaining-advanced
      chainWebpack: config => {
        enableShadowCss(config);
      }
    }
    

    使用上面的 sn-p 创建 &lt;projectroot&gt;/vue.config.js 可以在项目的开发模式下启用 Shadow CSS。见https://github.com/snirp/vue-web-component/pull/1

    【讨论】:

    • 这需要在 Vue 文档中!在过去的 2 天里,我一直在寻找这个答案。
    • 就我而言,在 Web 组件 + Typescript 设置中,即使在 vue.config.js 中使用上述内容,作为 JS 导入的样式也不会注入。唯一最终起作用的是将组件样式标记中的 scss 样式导入为:
    猜你喜欢
    • 2023-03-29
    • 2020-09-13
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2021-12-21
    • 1970-01-01
    • 2020-10-19
    相关资源
    最近更新 更多