Most people familiar with Angular 2+ know that in order to compile HTML templates one simply needs to add a template url in the component’s TypeScript file and be done with it. With Vue, the recommendation is to instead use template tags to build your template’s markup in the vast majority of cases.
We can use vue-template-loader if we want to use Vue with the Angular-way of building templates. Since vue-template-loader supports vue-class-component
we can use decorators on classes for class-styled components.
vue-template-loader compiles HTML into individual render functions in the respective TypeScript or JavaScript files.
We’ll need a typical seed Vue.js
project , along with webpack
dependencies.
Install vue-template-loader
using yarn
or npm
like this:
# yarn
$ yarn add vue-template-loader
# npm
$ npm install vue-template-loader
Now we can integrate vue-template-loader using webpack
.
Add vue-template-loader
as a rule in your webpack config file:
module.exports = {
module: {
rules: [
{
test: /\.html$/,
loader: 'vue-template-loader',
// We don't want to pass `src/index.html` file to this loader.
exclude: /index.html/,
}
]
}
}
Rendering the assets used in our HTML file like with processing the src attribute of ** tags can specified with options:
module.exports = {
module: {
rules: [
{
test: /\.html$/,
loader: 'vue-template-loader',
// We don't want to pass `src/index.html` file to this loader.
exclude: /index.html/,
options: {
transformToRequire: {
img: 'src'
}
}
}
]
}
}
Please note that for the above options to work we also need to add a loader to handle the image files (see file-loader).
If we want to use vue-template-loader with TypeScript we need to have the tsloader
and typescript
dependencies installed in the project along with webpack
.
vue-template-loader is used the same way in webpack’s config for both JavaScript and TypeScript.
The only addition will be in the typings folder of our project. We need to add the following shim in the typings folder to make TypeScript understand .vue files:
// To make TypeScript understand/import *.vue files, this shim is required
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
// TypeScript type module definition required for vue-template-loader
declare module '*.html' {
import Vue, { ComponentOptions } from 'vue';
interface WithRender {
<V extends Vue>(options: ComponentOptions<V>): ComponentOptions<V>
<V extends typeof Vue>(component: V): V
}
const withRender: WithRender
export = withRender
}
Now, let’s create an example with a template file that we’ll call nest.html
:
<div class="nest">
<p>{{ text }}</p>
<button type="button" @click="baz()">Click Me!</button>
</div>
Let’s add a nest.js
file corresponding to nest.html
. We can use vue-template-loader with or without class decorators when using es6 with Vue:
// Without class decorators in javascript
import withRender from './nest.html';
export default withRender({
data () {
return {
text: 'I\'m an alligator'
};
},
methods: {
baz () {
console.log('Clicked!');
};
};
});
// With decorators
import Vue from 'vue';
import Component from 'vue-class-component';
import WithRender from './nest.html';
@WithRender
@Component
export default class Nest extends Vue {
text = 'I\'m an alligator!';
baz() {
console.log('Clicked!');
}
}
It can also be used in TypeScript like this:
import Vue from 'vue';
import { Component } from 'vue-property-decorator';
import WithRender from './nest.html';
@WithRender
@Component({})
export default class NestComponent extends Vue {
data(){
return {
text: 'I\'m an alligator!'
}
};
baz(){
console.log('clicked!');
}
};
Using vue-template-loader provides great support for TypeScript, and can also decrease the number of files to be compiled as it eliminates .vue files. Lastly, it can be really easy to understand for people coming from an Angular background.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!