首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将VUE.JS组件转换为具有正确CSS样式的web应用程序

将VUE.JS组件转换为具有正确CSS样式的web应用程序
EN

Stack Overflow用户
提问于 2020-12-27 13:15:41
回答 1查看 562关注 0票数 0

我在src/App.vue下面有一个vue.js组件(vue多边形cropper),如下所示:

代码语言:javascript
复制
    <template>
        <div id="app">
            <h1 class="mb-4 mt-2 alert-success">Vue Image Cropper</h1>
            <div>
                <b-img :src="resultImage" alt="Responsive image" fluid v-show="showResult"></b-img>
                <div v-show="showResult">
                    <b-link :href="resultImage" download="result.png">Download Image</b-link>
                </div>
            </div>
            <div>
                <polygonCrop :canvasClass="'some-class'"
                             :height="600"
                             :imageSource="imgSrc"
                             :showCanvas="show"
                             :showPointer="showPointer"
                             :width="800"
                             ref="canvas"
                ></polygonCrop>
            </div>
            <b-row>
                <b-col>
                    <b-form-group>
                        <b-form-file
                                :state="Boolean(file)"
                                @change="setImage"
                                accept="image/*"
                                class="col-sm-6 mt-2"
                                drop-placeholder="Drop file here..."
                                placeholder="Choose a file or drop it here..."
                                size="lg"
                                v-model="file"
                        ></b-form-file>
                        <div class="mt-3">Selected file: {{ file ? file.name : '' }}</div>
                    </b-form-group>
    
                    <b-button @click.prevent="crop" variant="success">Crop</b-button>
                    <b-button @click.prevent="undo" variant="warning">Undo</b-button>
                    <b-button @click.prevent="redo" variant="primary">Redo</b-button>
                    <b-button @click.prevent="reset" variant="danger">Reset</b-button>
                </b-col>
            </b-row>
        </div>
    </template>
    <script>
        // import polygonCrop from '../../dist/PolygonCropper.umd';
        import polygonCrop from 'vue-polygon-cropper';
    
        export default {
            name: 'App',
            data() {
                return {
                    imgSrc: '/demo.png',
                    file: null,
                    show: false,
                    showResult: false,
                    showPointer: true,
                    resultImage: ""
                };
            },
            components: {
                polygonCrop
            },
            methods: {
                setImage(e) {
                    const file = e.target.files[0];
                    if (!file && file.type.indexOf('image/') === -1) {
                        alert('Please select an image file');
                        return;
                    }
                    if (typeof FileReader === 'function') {
                        const reader = new FileReader();
                        reader.onload = (event) => {
                            this.imgSrc = event.target.result;
                            this.show = true;
                        };
                        reader.readAsDataURL(file);
                    } else {
                        alert('Sorry, FileReader API not supported');
                    }
                },
                crop: function () {
                    this.$refs.canvas.crop();
                    this.resultImage = this.$refs.canvas.resultImage;
                    this.show = false;
                    this.showResult = true;
                },
                undo: function () {
                    this.$refs.canvas.undo();
                },
                redo: function () {
                    this.$refs.canvas.redo();
                },
                reset: function () {
                    this.show = true;
                    this.showResult = false;
                    this.$refs.canvas.reset();
                }
            }
        };
    </script>
    
    <style>
        #app {
            font-family: Avenir, Helvetica, Arial, sans-serif;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            text-align: center;
            color: #2c3e50;
            margin-top: 60px;
        }
    
        .some-class {
            border: 1px solid #2c3e50;
        }
    </style>

src目录下的main.js如下所示:

代码语言:javascript
复制
    import Vue from 'vue';
    import App from './App.vue';
    import {BootstrapVue, IconsPlugin} from 'bootstrap-vue';
    import 'bootstrap/dist/css/bootstrap.css';
    import 'bootstrap-vue/dist/bootstrap-vue.css';
    
    Vue.config.productionTip = false;
    Vue.use(BootstrapVue);
    Vue.use(IconsPlugin);
    
    new Vue({
        render: h => h(App),
    }).$mount('#app');

我需要将其转换为web组件,因此我在vue.config.js文件中做了一些更改,以使用正确的CSS样式:

代码语言:javascript
复制
    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('normal-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'),
      ];
      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);
      }
    }

问题是,当我生成一个web组件时:

代码语言:javascript
复制
npm run build -- --target wc --name app-1

它在dist文件夹中生成web组件,如下所示,但是当我转到demo.html时,它没有正确地呈现CSS,而且组件也没有正确显示:

代码语言:javascript
复制
C:\ThermoAnalyser\vue_js\project1\dist>dir
 Volume in drive C is Windows-SSD
 Volume Serial Number is 18EE-B4F6

 Directory of C:\ThermoAnalyser\vue_js\project1\dist

27/12/2020  11:24 PM    <DIR>          .
27/12/2020  11:24 PM    <DIR>          ..
27/12/2020  11:24 PM            46,521 app-1.js
27/12/2020  11:24 PM            55,715 app-1.js.map
27/12/2020  11:24 PM            18,236 app-1.min.js
27/12/2020  11:24 PM            71,872 app-1.min.js.map
27/12/2020  11:24 PM               149 demo.html
               5 File(s)        192,493 bytes
               2 Dir(s)  300,479,696,896 bytes free

同样,当我跑步时:

代码语言:javascript
复制
npm run build

它给了我这个错误:

代码语言:javascript
复制
-  Building for production... ERROR  TypeError: Cannot set property 'shadowMode' of undefined
TypeError: Cannot set property 'shadowMode' of undefined
    at C:\ThermoAnalyser\vue_js\project1\vue.config.js:26:24
    at Object.tap (C:\ThermoAnalyser\vue_js\project1\node_modules\webpack-chain\src\Use.js:14:20)
    at C:\ThermoAnalyser\vue_js\project1\vue.config.js:25:26
    at Array.forEach (<anonymous>)
    at enableShadowCss (C:\ThermoAnalyser\vue_js\project1\vue.config.js:25:11)
    at chainWebpack (C:\ThermoAnalyser\vue_js\project1\vue.config.js:34:5)
    at C:\ThermoAnalyser\vue_js\project1\node_modules\@vue\cli-service\lib\Service.js:236:40

如果有人能帮助我用正确的CSS样式生成代码的web组件,我将非常感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-31 01:44:35

您在enableShadowCss()中拥有的vue.config.js代码仅用于开发模式。shadowMode已经在生产构建中启用了,所以这不会对您的构建过程有所帮助,您应该删除它。

BootstrapVue组件没有在您的主应用程序中初始化,因此您将在浏览器控制台中看到错误消息,指示未知组件。

要启用第三方组件,可以在要导出的目标组件中初始化BootstrapVue (本例中为src/App.vue):

代码语言:javascript
复制
<script>
import {BootstrapVue, IconsPlugin} from 'bootstrap-vue';

Vue.config.productionTip = false;
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);

export default {
  //...
}
</script>

此外,您还需要导入目标组件的<style>块中的样式,以便将它们包含在组件的Shadow中:

代码语言:javascript
复制
<style>
@import '~bootstrap/dist/css/bootstrap.css';
@import '~bootstrap-vue/dist/bootstrap-vue.css';

/*...*/
</style>

GitHub PR

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65466163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档