Skip to content

Writing Vue Applications

You can write version 3 Vue applications right from the start. If you do so Vue would be compiled into your final JavaScript file. To avoid this you can use like before a @cc-external package:

1
npm i @cc-external/vue

First of all we create a vue file 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.
  • 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 the Vetur extension. Of course you can use here all proposals as with a regular CSS file as described before.

srv/amazing-button.vue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<template>
  <div class="amazing-button card h-100">
    <div class="card-header">
      Amazing Vue Button <i class="fa fa-magic"></i>
    </div>
    <div class="card-body">
      <h5 class="card-title">Click on the button to see the miracle</h5>
      <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="logo.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 {
  --my-color: #f30000;
  & .card-header {
    color: var(--my-color);
    background-image: url(logo.png);
    background-size: contain;
    background-repeat: no-repeat;
    background-position-x: left;
  }
  & .card-title {
    text-decoration: underline;
  }
}
</style>

We create a class for the sake of simplicity to keep the same interface:

src/amazing-button-vue.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import $ from "jquery";
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");
    $(element).css({
      border: "1px solid red",
      textAlign: "center"
    });
    this.vueApp = createApp(AmazonButtonVue).mount(element);
  }
}

Let's add a fourth container in our static HTML file in which we will start the Vue application:

static/index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <title>CodeCoupler</title>
    <style>
      .test-container {
        width: 400px;
        height: 350px;
        margin: 100px;
        border: 1px solid green;
        float: left;
      }
    </style>
  </head>

  <body>
    <div id="test-container-vanilla" class="test-container"></div>
    <div id="test-container-jquery" class="test-container"></div>
    <div id="test-container-bootstrap" class="test-container"></div>
    <div id="test-container-vue" class="test-container"></div>
    <div class="test-container" style="overflow: scroll">
      <%= htmlWebpackPlugin.tags.headTags %>
    </div>
    <div class="test-container" style="overflow: scroll">
      <%- include inc/part.html %>
    </div>
  </body>
</html>

Finally we will change the index.js and start our new Vue based library in the fourth container:

src/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { default as MyVanillaApp } from "./amazing-button-vanilla";
import { default as MyJQueryApp } from "./amazing-button-jquery";
import { default as MyBootstrapApp } from "./amazing-button-bootstrap";
import { default as MyVueApp } from "./amazing-button-vue";

let myVanillaInstance = new MyVanillaApp(
  document.getElementById("test-container-vanilla")
);
myVanillaInstance.maximumNumber = 99;

let myJQueryInstance = new MyJQueryApp(
  document.getElementById("test-container-jquery")
);
myJQueryInstance.maximumNumber = 49;

let myBootstrapInstance = new MyBootstrapApp(
  document.getElementById("test-container-bootstrap")
);
myBootstrapInstance.maximumNumber = 79;

let myVueInstance = new MyVueApp(document.getElementById("test-container-vue"));
myVueInstance.maximumNumber = 39;

Now you should see the running example in your browser.