Welcome to Part III which will be the last part of this series. In Part I and Part II we started to create a generator for a Vue component. In Part I we started very easy and looked at what we need for a Vue component and build our first generator with hygen. This generator helped us to create a new dynamic Vue component over the CLI. In Part II we expand our generator and made him interactive with the prompt functionality from hygen and started to ask some questions of the new Vue component which we want to create with the CLI.
Plan
Today I want to show you how you can create more than one file and bring much more dynamic in your generator.
Generate more than one file
I’m a big fan of the methodology of Separation of Concerns. In my personal projects, I have a src/components/
folder and in this folder, I have again a folder for every component. These folders include than different files as *.js
for logic, *.scss
for styling, *.vue
for the component itself and one *.html
for a template.
Ok, we know how to create one file with our _templates/vue-component/new/hello.ejs.t
. To create now more than one is easier than you think: Create more template files!
We rename our filehello.ejs.t
to vue.ejs.t
and create 3 other files like js.ejs.t
, css.ejs.t
and html.ejs.t
. After that, we should have files like this.
Now we must edit all files that they generate what we want. Our goal should be the new files system from above.
Edit vue.ejs.t
---
to: src/components/<%= name %>/<%= name %>.vue
---
<template src="./<%= name %>.html"></template>
<script src="./<%= name %>.js"></script>
<style scoped src="./<%= name %>.scss"></style>
What we did here is to set a new target for creating the file to src/components/<%= name %>/<%= name %>.vue
. And remove everything from the blocks template ,script and style and reference to the new source file where the code will be.
Edit css.ejs.t
---
to: src/components/<%= name %>/<%= name %>.css
---
.<%= name.toLowerCase() %> {
position: relative;
}
The same for the css file. A new target of creating the file and include default class with the name of the component.
Edit js.ejs.t
---
to: src/components/<%= name %>/<%= name %>.js
---
<% if(axios){ -%>
import axios from 'axios'
<% } -%>
export default {
name: "<%= name %>",
props: {
msg: String
},
methods: {
<%_ if(axios){ -%>
async fetchData() {
try {
const response = await axios
.get('https://api.endpoint.com')
.then(function(response) {
console.log(response)
})
.catch(function(error) {
throw new Error(error)
})
return response
} catch (error) {
throw new Error(error)
}
}
<%_ } -%>
}
};
Again we define a new target for creating the file and put everything from the script
block into it.
Edit html.ejs.t
---
to: src/components/<%= name %>/<%= name %>.html
---
<div class="<%= name.toLowerCase() %>">
<h1>My new Vue Component with the name <%= name %></h1>
</div>
Here the new target for creating and the code block for the template.
Hopefully, this works now as it should and create a new folder in our scr/components
folder with the name of our new component. Plus 4 new files. Let’s go
hygen vue-component new
We will get our normal questions about the name and axios. After that we should get a result from our generator like this:
Great! It works and we created now a new component in a new folder with 4 files.
Injects
Now we optimize a little bit our generator in our final part. We include sometimes axios in our new components but we don’t add the package to our packgaes.json
and this will not work later.
To include something in files that exists we can use the propertyinject in our template file. We learned right now that for every new action or creating a new file we must create a new template file. We will do here the same and create a new template file called axios.ejs.t
.
---
inject: true
to: package.json
after: dependencies
skip_if: axios
---
<% if(axios){ -%>
"axios":"*",
<% } -%>
To explain what happens here is very simple. First, we set inject: true
which means we want to inject something. The second is familiar to us. We set to: packages.json
because we want to inject something into our package.json file. Then we define where we want to inject something at the package.json. With after: dependencies
we define that we want to include our code into the dependencies object in our package.json file. And finally, we define with skip_if: axios
our injection when axios already exists in our package.json file.
In the code block, we have only a condition if the new component need axios, then we inject it. Because like our other files will hygen call this template file by every time when we create a new component. But sometimes maybe we don’t want to have axios at all and then it is not in our package.json file.
Now we can test it by creating a new component with our generator.
hygen vue-component new
We will create a new component and answer the question about axios with ‘y’.
You can see the purple message in the CLI inject: package.json
. Now let’s check if it did what we wanted.
Awesome! It works!
Now, whenever you use your generator and create a new component the inject file will run through your generator but only includes axios in your package.json when the new component depends on but not when it is already set up in your package.json.
Conclusion That was it! I hope you enjoyed my first tutorial series, had fun and learned something which will help you with your daily work. Hygen has much more potential as I can show here and feel free to do much more than me here. Maybe I will read next a tutorial from you about hygen.
You will find our last changes again in this repository.
You will find more in the other parts: