Switch to Vue
Now that we know how to create a system with applications, let us rewrite some of the components as
a Vue application. This can be done for a Stage and a Widget.
Stages as Vue Application
Let's start with our header stage and rewrite the functionality as Vue application:
stage/header.vue
| <template>
<div class="header-stage d-flex flex-column h-100">
<div class="header text-white">
Header as Vue with option: {{ options.header }}
</div>
<div class="flex-grow-1 position-relative" data-role="cc-stage"></div>
</div>
</template>
<script>
export default {
props: {
env: { type: Object, default: null },
options: { type: Object, default: null }
}
};
</script>
<style lang="postcss" scoped>
.header-stage {
& .header {
background-color: var(--color-primary-2);
min-height: 40px;
padding: 10px;
}
}
</style>
|
lang=postcss
As you can see the attribute lang=postcss
was set in the <script>
section. This was done to
make the syntax highlighting and formatting of Visual Code and Vetur work together.
Now we replace in our index.js
the module we import and add only a property type: "vue"
into the
stage definition:
index.js
| import { System, Sidebar } from "@codecoupler/cc-ui";
import HeaderStage from "./stages/header.vue";
import apps from "./apps.js";
import "./style.css";
import "./sidebar.css";
let system = new System({
id: "codecoupler-walkthrough",
apps: apps,
stages: [
{
stage: Sidebar,
options: { logo: "logo.png" }
},
{
type: "vue",
stage: HeaderStage,
options: { header: "Test" }
}
],
panel: {
setStatus: "maximized",
header: false
}
});
system.initialized
.then((system) => {
console.info("System is Ready!", system.id);
})
.catch((e) => {
console.error(e);
if (!e.systemBlocked)
document.body.innerHTML = "Oops, Something went wrong!";
});
|
The header is now a Vue application. The files stage/header.html
, stage/header.css
and
stage/header.js
are not needed anymore.
The Vue application receives the arguments env
and options
now as props:
As plain JS |
As Vue |
async init(env, options) {} |
props: { env: { ... }, options: { ... } } |
The argument env
has one more property named stage
which points to the stage instance as it
would be if the stage is written in plain JavaScript.
Single root and Multiple roots
As of Vue 3 you are not limited to a single root element in the template anymore. This is an
extremely useful feature but within the CodeCoupler system you have to pay attention to the following:
If you are using a single root template you have to set the type to vue
or vue-sr
.
If you are using multiple root elements you have to set the type to vue-mr
.
Now let's rewrite one of our widgets as a Vue application:
widgets/testing-visibility.vue
| <template>
<div>
<h1>Visibility Testing <span>Vue</span> Widget!</h1>
<p>Text: {{ options.text }}</p>
</div>
</template>
<script>
export default {
props: {
env: { type: Object, default: null },
options: { type: Object, default: null }
},
mounted: function () {
//Bind to an own event "visibilitychanged".
this.env.widget.on("visibilitychanged", () => {
console.info(
`${this.options.text}: fullvisible is ${this.env.widget.fullvisible}`
);
});
console.info(
`${this.options.text}: fullvisible is ${this.env.widget.fullvisible}`
);
}
};
</script>
<style lang="postcss" scoped>
h1 {
color: red;
& span {
color: green;
}
}
</style>
|
lang=postcss
As you can see the attribute lang=postcss
was set in the <script>
section. This was done to
make the syntax highlighting and formatting of Visual Code and Vetur work together.
Now we replace in our application that uses this widget the module we import, the property type
inside the widget definition and switch from the property widget
to vue
:
apps/testing-buttons.js
| import { Application, Layout } from "@codecoupler/cc-ui";
import buttons from "./custom-buttons";
import MyFirstWidget from "../widgets/my-first-widget.js";
import TestingSizingWidget from "../widgets/testing-sizing";
import TestingVisibilityWidget from "../widgets/testing-visibility.vue";
export default class extends Application {
static ui = {
name: "Testing Buttons",
iconHtml: '<i class="fas fa-seedling fa-fw"></i>'
};
async init() {
let layout = {
header: {
show: true
},
root: {
type: "row",
content: [
{
type: "widget",
title: "Number 1",
widget: TestingSizingWidget,
options: {
text: "Hallo Everyone"
}
},
{
type: "column",
content: [
{
type: "widget",
title: "Number 2",
widget: MyFirstWidget,
options: {
text: "How are you?"
}
},
{
type: "stack",
content: [
{
type: "widget",
title: "Number 3",
widget: MyFirstWidget,
options: {
text: "I'm fine, thanks!"
}
},
{
type: "vue",
title: "Number 4",
vue: TestingVisibilityWidget,
options: {
text: "Widget Number 4"
}
}
]
}
]
}
]
}
};
await super.init({
panel: {
panelSize: "820 600",
headerTitle: "My First Title",
footerToolbar:
'<i class="far fa-hand-point-right mx-1"></i> [inline][blocks][hints][alerts][close]'
},
buttons: buttons,
widget: {
widget: Layout,
options: layout
}
});
}
}
|
The widget is now a Vue application. The file widgets/testing-visibility.js
is not needed anymore.
The Vue application receives the arguments env
and options
now as props:
As plain JS |
As Vue |
async init(env, options) {} |
props: { env: { ... }, options: { ... } } |
The argument env
has one more property named widget
which points to a widget instance as it
would be if the widget is written in plain JavaScript.
Single root and Multiple roots
As of Vue 3 you are not limited to a single root element in the template anymore. This is an
extremely useful feature but within the CodeCoupler system you have to pay attention to the following:
If you are using a single root template you have to set the type to vue
or vue-sr
.
If you are using multiple root elements you have to set the type to vue-mr
.