Skip to content

Latest commit

 

History

History
96 lines (86 loc) · 3.41 KB

揭秘vue - Vue生成web components.md

File metadata and controls

96 lines (86 loc) · 3.41 KB

  首先生成vue项目:

vue create v-card

  在components目录中新建自定义组件VCard.vue。

<template>
  <div style="text-align: center; font-family: sans-serif">
    <h1>{{title}}</h1>
    <p>{{name}}</p>
  </div>
</template>

<script>

export default {
  name: 'VCard',
  props: {
    title: {
      type: String,
      default: ''
    },
    name: {
      type: String,
      default: ''
    }
  },
  components: {
  }
}
</script>

  修改main.js

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

import VCard from './components/VCard.vue';


const wrappedElement = wrap(Vue, VCard);

window.customElements.define('v-card', wrappedElement);

  执行命令,生成web components组件。

npm run build -- --target wc --name v-card src/components/VCard.vue

  <style>样式将会注入build之后的web components组件,但开发环境并不会生效。解决这个问题需要修改vue.config.js。参见:Styling not applied to vue web component during development

vue.config.js

var webpackConfig = require("@vue/cli-service/webpack.config");


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 = {
  chainWebpack: config => {
    enableShadowCss(config);
  }
}