I have a vue.js component (vue polygon cropper) under src/App.vue like below:
<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>
My main.js under src directory is as follows:
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');
I need to do to convert this to web component, so I have done some changes in vue.config.js file to use the correct CSS styling:
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);
}
}
The problem is that when I generate a web component:
npm run build -- --target wc --name app-1
And it generates the web component inside dist folder as follows, but when I go to demo.html, it doesn't render CSS correctly, and the component doesn't show up correctly:
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
Also when I run:
npm run build
It is giving me this error:
- 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
I would greatly appreciate if someone help to generate the web component of my codes with correct CSS styling?