web-dev-qa-db-ja.com

開発中にvue Webコンポーネントにスタイリングが適用されない

Vue Webコンポーネント)の開発中、styleはWebコンポーネントには適用されませんが、ドキュメントのheadに追加されます。つまり、スタイルシャドウ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ルールは有効になりません。

実動用にビルドすると、スタイルがWebコンポーネントに追加されます。次のコマンドを使用してラッピングを行います。

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:私の問題は この問題 と密接に関係していると感じています。私は回避策をあまり理解できず、より基本的な解決策を評価します。

16
Roy Prins

リンクしたGitHubの問題に基づいて、 solution は_vue-loader_で shadowModeオプションを設定します および_vue-style-loader_。 shadowModeは、Vue CLIプロジェクトではデフォルトでfalseですが、 _vue.config.js_で調整できます

最初に、 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')
_

したがって、このスニペットを使用して、_shadowMode: true_の構成に_vue.config.js_を設定できます。

_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);
  }
}
_

上記のスニペットで_<projectroot>/vue.config.js_を作成すると、プロジェクトの開発モードでShadow CSSが有効になります。 https://github.com/snirp/vue-web-component/pull/1 を参照してください。

7
tony19