Writing Vue Applications
To write Vue applications you have to install the vue
package:
Importing vue components like in import { createApp } from "vue";
would lead to including the Vue
library into your final JavaScript file. To avoid this you can add like before the following
externals configuration:
webpack.config.js
| const ccWebpack = require("@codecoupler/cc-webpack");
module.exports = (env) =>
ccWebpack(
{
externals: [
{
module: "vue",
global: "Vue",
entries: ["dist/vue.runtime.global.prod.js"]
},
{
module: "jquery",
global: "jQuery",
entries: ["dist/jquery.min.js"]
},
{
module: "bootstrap-icons",
entries: ["font/bootstrap-icons.min.css"],
copy: ["font/fonts"]
},
{
module: "bootstrap",
entries: ["dist/js/bootstrap.bundle.min.js"]
}
]
},
env,
{}
);
|
First of all we create a Vue Single File Component with all the parts we have written separately
(HTML, JavaScript, CSS).
- The HTML part was put into the
<template></template>
section. Only a few small adjustments have
been made here. Important: Links to assets have to start with ./
.
- The logic of the class was included in the
<script></script>
section. This part can be written
very briefly. Of course you can use here all proposals as with a regular JavaScript file as
described before.
- The stylesheet was included in the
<style lang="postcss" scoped></script>
section. Please note
the lang="postcss"
attribute. This is useful to work Visual Code validator together in
combination with the Vetur extension. Of course you can use here all proposals as with a regular
CSS file as described before.
srv/amazing-button.vue
| <template>
<div class="amazing-button-vue card h-100">
<div class="card-header">Amazing Vue Button</div>
<div class="card-body">
<p class="card-text">
<button class="btn btn-secondary" @click="amazingFunction">
Show number from 1 to {{ maximumNumber }}
</button>
</p>
<div class="result border border-primary mb-2">
{{ resultingNumber ?? "No Result" }}
</div>
<img src="./images/favicon.png" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
maximumNumber: 9,
resultingNumber: null
};
},
methods: {
amazingFunction() {
this.resultingNumber = Math.floor(Math.random() * this.maximumNumber);
}
}
};
</script>
<style lang="postcss" scoped>
.amazing-button-vue {
--my-color: #f30000;
text-align: center;
& .card-header {
color: var(--my-color);
background-image: url(images/favicon.png);
background-size: contain;
background-repeat: no-repeat;
background-position-x: left;
}
}
</style>
|
We create a class for the sake of simplicity to keep the same interface and mounts our Vue
application:
src/amazing-button-vue.js
| import { createApp } from "vue";
import AmazonButtonVue from "./amazing-button.vue";
export default class {
get maximumNumber() {
return this.vueApp.maximumNumber;
}
set maximumNumber(value) {
this.vueApp.maximumNumber = value;
}
constructor(element) {
console.debug("Starting Vue Button");
this.vueApp = createApp(AmazonButtonVue).mount(element);
}
}
|
Let's add another container in which we will start the new class:
src/index.js
| import createTestContainer from "./create-test-container";
import { default as MyVanillaApp } from "./amazing-button-vanilla";
import { default as MyPackagesApp } from "./amazing-button-packages";
import { default as MyImportApp } from "./amazing-button-import";
import { default as MySvgApp } from "./amazing-button-svg";
import { default as MyDynamicApp } from "./amazing-button-dynamic";
import { default as MyVariableApp } from "./amazing-button-variable";
import { default as MyVueApp } from "./amazing-button-vue";
import "./style.css";
createTestContainer("Testing Vanilla JS", "test-container-vanilla");
let myVanillaInstance = new MyVanillaApp(
document.getElementById("test-container-vanilla")
);
myVanillaInstance.maximumNumber = 99;
createTestContainer("Testing Packages", "test-container-packages");
let myPackagesInstance = new MyPackagesApp(
document.getElementById("test-container-packages")
);
myPackagesInstance.maximumNumber = 49;
createTestContainer("Testing Import HTML/CSS/Assets", "test-container-import");
let myImportInstance = new MyImportApp(
document.getElementById("test-container-import")
);
myImportInstance.maximumNumber = 79;
createTestContainer("Testing Import SVG", "test-container-svg");
new MySvgApp(document.getElementById("test-container-svg"));
createTestContainer("Testing Dynamic Imports", "test-container-dynamic");
let myDynamicInstance = new MyDynamicApp(
document.getElementById("test-container-dynamic")
);
myDynamicInstance.maximumNumber = 55;
createTestContainer("Testing CSS/EJS Variables", "test-container-variable");
let myVariableInstance = new MyVariableApp(
document.getElementById("test-container-variable")
);
myVariableInstance.maximumNumber = 45;
createTestContainer("Testing Vue", "test-container-vue");
let myVueInstance = new MyVueApp(document.getElementById("test-container-vue"));
myVueInstance.maximumNumber = 12;
|
With npm start
you should see the running example in your browser.