First, we need to create our Vue CLI project. To find how to create a Vue CLI project, please check the 'Creating your first project with Vue CLI' recipe. We can use the one we created in the last recipe or start a new one.
Follow these steps to create your custom function decorator with vue-class-component:
- Create a file called componentMount.js inside the src/decorators folder.
- We need to import the createDecorator function from the vue-class-component to be able to use it on a vue-class-component based component, and to start coding our decorator:
import { createDecorator } from 'vue-class-component';
import componentMountLogger from './componentLogger';
export default createDecorator((options) => {
options.mixins = [...options.mixins, componentMountLogger];
});
A createDecorator function is like an extension of the Vue vm (View-Model), so it won't have the property of an ECMAScript decorator but will function as a Vue decorator.
- We need to use the componentLogger.js file in our decorator. This function will take all the data values that are set in the "decorated" component and add a watcher to it. This watcher will log the new and old values whenever it changes. This function will only be executed with a debug data set to true:
export default {
mounted() {
if (this.debug) {
const componentName = this.name || '';
console.log(`The ${componentName} was mounted
successfully.`);
const dataKeys = Object.keys(this.$data);
if (dataKeys.length) {
console.log('The base data are:');
console.table(dataKeys);
dataKeys.forEach((key) => {
this.$watch(key, (newValue, oldValue) => {
console.log(`The new value for ${key} is:
${newValue}`);
console.log(`The old value for ${key} is:
${oldValue}`);
}, {
deep: true,
});
});
}
}
},
};
- Now, we need to import the decorator to our Counter.vue component file located in the src/components folder and add the debugger data to it:
<template>
<div>
<fieldset>
<legend>{{ this.formattedNumber }}</legend>
<button @click="increase">Increase</button>
<button@click="decrease">Decrease</button>
</fieldset>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import componentMount from '../decorators/componentMount';
@Component
@componentMount
export default class Counter extends Vue {
valueNumber: number = 0;
debug: boolean = true;
get formattedNumber() {
return `Your total number is: ${this.valueNumber}`;
}
increase() {
this.valueNumber += 1;
}
decrease() {
this.valueNumber -= 1;
}
}
</script>