I spent a few days on and off learning parts of Vue to write a small app. I wrote the same app with Angular. I'm sharing my experience of working through Vue for the first time to help others that may be curious about the JavaScript framework landscape.
Hello and welcome to this tutorial on Vue.JS with Visual Studio Code. In this series of tutorials, we will see how we can work with Vue.JS with VS Code and learn more about Vue.JS. Its a front end.
- Vue.js Examples Ui Scroll. Vue.js + LokiJS A simple test to get LokiJS working with Vue.js. Eventually I'll (hopefully) extend this to work with Phonegap, and get some persistent data going. Lokijs is Fast document oriented. Code BY Dzulfikar Adi Putra codepen demo See the Pen Vue v1 Search and Pagination by Dzulfikar 02 March 2017.
- When you’re finished installing and are now in Visual Studio Code, open the src/App.vue file. You will notice that there’s no syntax highlighting, as is shown in the following figure: Visual Studio Code will warn you, in the lower right corner, that there are extensions for Vue. Here are some good extensions to start with: Vue; Vue 2.
- Vuejs Form Example Summary. We learned a good deal about forms and VueJs in this tutorial. We covered how to use all of the standard html form controls in addition to creating our very own custom control as a Vue component.
This post explores how I refactored the Vue app to use TypeScript. The two places I found the most help were in this (Microsoft resource](https://github.com/microsoft/typescript-vue-starter) and the Vue docs. Neither was exactly what I needed, but together they were helpful in gaining success. Read on to learn more.
Disclaimer: This was my first attempt at using TypeScript in Vue. My intent is to share the journey, not to claim this is the 'best' way to use TypeScript. I know TypeScript well, but I am learning Vue and leaning on the experts from the Vue document and TypeScript team's resources on Vue for much of what I accomplished. I give credit to both of these teams for making these resources available and helping the community.
Why TypeScript?
Hold on a second .. Why? I mean, why use TypeScript at all? JavaScript is awesome, why do we need TypeScript? Well, we don't *need it. But I want it. But again .. why? Why do I want TypeScript? This is a question we should always ask when someone tells us we should use something. Far too often we find ourselves reading how to do something .. but the why is often far more important.
Simply put TypeScript allows me to code faster and to catch and rectify more problems at development time than without it. Intellisense, auto-complete, and great tooling are enabled when editors can use the TypeScript features. Need some examples? OK .. We can tell what the return type of an asynchronous function is an array of Hero models. Or we can find that we use a heroes
array in one place as an array and in another as an ES promise. When the editor is smarter, I can adapt quickly and fix problems before I deploy.
If you are interested in how I got started with Vue, here are some other posts that may interest you:
- Post 1 - File Structure
- Post 2 - Learning Materials
- Post 3 - Familiar Code
- Post 4 - Vue.js with TypeScript
Setup
I had to start somewhere, so I started by branching off of my connect2017
branch in this repo. This gave me a functional Vue app out of the box that I could begin refactoring to use with TypeScript.
I started by adding in the files that tell TypeScript how to do its job.
tsconfig.json
The first new file is tsconfig.json
. I started with the file that the Vue documentation recommends here. Then I enhanced it a bit. I found the changes to be super helpful.
The following file tells TypeScript to put the compiled JavaScript in the ./built
folder, to generate source maps for debugging and use TypeScript decorators (among other settings). I also added in lib
support for some core ES2016 features.
webpack.config.js
I knew I needed to change how the build process worked. For this, I opened the webpack.config.js
and immediately started to Google for some help. I find WebPack configuration to be painful .. hey, it's an awesome tool, but I admit that it's not easy for me to figure out what I need to modify in there. Luckily I found this guide by the TypeScript team that showed how to modify the file.
These are the git changes I made to my file.
We can see that the entry
file is now the main.ts
instead of main.js
. That makes sense. Then there are settings for a ts-loader
, which helps load the TypeScript with Vue. Finally, I added some extensions to the resolve
section.
Do I expect this is all perfect? Nope. It works .. and this is the kind of thing that once the Vue CLI adds a TypeScript template to its tooling, we won't have to mess with it at all. So let's proceed.
npm packages
I'm adding TypeScript to the project so it makes sense that I had to add some packages to support this. (The Vue CLI should handle this once it adds the new TypeScript template, too.)
First I ran npm install typescript ts-loader --save-dev
to add them as a development dependency. This came from the helpful Microsoft doc here. I deviated from that helped doc because I already had some of the others and I like to code dangerously.
Next, I ran npm install vue-property-decorator vue-class-component --save
to install support for the TypeScript decorators. The decorators will help define classes as Vue components and define props
.
Note: The @Component()
decorator is in vue-class-component
but it is imported and re-exported from vue-property-decorator
. So you can import from both of these, or just the latter. But you will want to npm install
both.
vue.shims.d.ts
We can define files that help TypeScript and the tooling know how to handle some specific types. The helpful Microsoft doc here suggested adding the following code to a new file named vue.shims.d.ts
. It basically makes it easier for the tooling to know how to handle *.vue
files, also known as Single File Components (SFC).
Refactoring the Code Files
A great way to look at the changes required during my refactor is to use a file by file comparison. Let's begin.
main.js --> main.ts
I renamed the main.js
file to main.ts
. Yep, no code changes in this one. Move along.
App.vue
The App
component is the root component in the Vue app. Here is its original file using Babel with JavaScript.
The next image shows the TypeScript. Take a glance, then read on to learn how I refactored the code to get here.
First, I added a hint to the <script>
tag to let it know I will be using TypeScript. Notice the tag is now <script>
in the image below.
I added the @Component()
decorator to both tell Vue that the class following the decorator is indeed a Vue component and that this component will reference a child component named HeroList
. This components
property in the decorator was lifted right from the components
property in the JavaScript example.
I refactored the default export to become a named class App
that extends Vue
. This makes sense as the name of our component is App
. We extend Vue
as a way of preparing our class to be a component. See an example in the Vue docs here.
I refactored the data
properties to become public class properties. Then I initialized the title property in the constructor. I could also have done this in a lifecycle event, which probably makes more sense.
Notice I added a few import
statements to the top of the file. This helped the tooling and TypeScript know where to get the Vue
and Component
symbols.
HeroList.vue
The HeroList.vue
file contains the logic for getting and displaying the heroes. The JavaScript version is shown below for reference. Notice I collapsed the components
and methods
to make it easier to follow. Full source code can be found at the end of this post.
Here follows the TypeScript version of the file, after my refactoring effort. Take a moment to see the differences and how they map to each other.
Just as with the App.vue
file, the components
moved up to the decorator and the data
properties became public class properties. There are some subtle differences here though as we look closer. Notice that I added explicit types to selectedHero
and heroes
. I did not need to do this, but it helped clarify things.
The selectedHero
was initialized to null
so the details wouldn't appear until a selection had been mad. But now that I have a Hero
type
(we'll explore that in the next section), I wanted to be clear to the compiler of my intentions that the selectedHero
should be allowed to be null
or of type Hero
.
But perhaps far more interesting is how I went from initializing the heroes
array right in the data function in the JavaScript example to initializing it in the created
life cycle event in the TypeScript example. This is one place I found a bug in the JavaScript example. I was setting the heroes to the return value from the getHeroes
function .. which was not an array of heroes, but instead a promise
of an array of heroes. This did not bite me in the running code because I was, but it could have. It worked only because the getHeroes
function sets the heroes
array .. so it immediately ran and filled the array anyway. But this just hid the bug. When I refactored it to use TypeScript the editor alerted me that I had a type mismatch. Then I moved the call to getHeroes
to the created
lifecycle event. Ladies and gentlemen, that's a real bug .. not something I staged. Oops! But thankfully the editor caught my mistake and I was able to correct it during the refactor.
We also have some new imports up top in the TypeScript file and I added some more explicit typings in a few places, so I could make sure I had no more hidden bugs. That's the value of setting noImplicityAny: true
in the tsconfig.json
file.
Hero Model
Now that I have types, I added a hero.ts
file to define a Hero
class. This helped make sure the components that deal with heroes are using the right types and properties.
HeroDetail.vue
The HeroDetail
component had many of the same changes as the HeroList
component. Some imports up top, the @Component()
decorator, moving the data
properties to public class properties, and defining some explicit types.
Check out the JavaScript version here.
Now take a glance at the TypeScript version, after the refactoring effort.
What's new here is that I am using the @Props()
, @Watch()
, and @Emit()
decorators in the TypeScript version. Notice the hero
that I was watching in the JavaScript version is now a public class property decorated with @Prop()
. This was a simple refactoring.
Then I defined a named function onHeroChanged
and decorated it with the @Watch()
decorator. This went from a function named hero
in the JavaScript version to a named function with a @Watch()
decorator in the TypeScript version.
Dell hid compliant touch screen driver. I converted the code where I emitted events using this.$emit
in JavaScript to now use the @Emit()
decorator. This decorator accepts the name of the event being emitted. The receiving function in the HeroList
component also was slighlty refactored, since now I am emitting 2 arguments instead of one. Here is an example of how I refactored these emitters:
I access the $refs
to grab the elements to set focus on them. I made a public class property named $refs
and typed it with the names of the two references I had in the Vue template. Both are of type HTMLElement
.
Hero Service
The hero service refactor was quite simple. The TypeScript version became an instance of a class that I could import into the components and use as needed. Nothing out of the ordinary here. This could have simply been a set of exported functions, too. There are lots of ways to handle services in JavaScript/TypeScript.
Summary
The best question to ask is 'was it worth it?'. Only you can decide. I think it was worth it. It caught a bug I had in the JavaScript version and now I get a lot more help from my tools, like VS Code, when writing the app.
I'm looking forward to the official TypeScript template for the Vue CLI. But in the meantime, there are a few ways to use TypeScript with Vue projects.
Source Code
You can find the source code for these apps here:
- Angular / TypeScript app - in the
vue-similar
branch - Vue / JavaScript app - in the
connect2017
branch - Vue / TypeScript app - in the
typescript
branch
Building your first Vue.js App with ASP.NET Core 2 and Vuetify
Vue.js (https://vuejs.org/) is a great front-end framework, especially for beginners. There are several single page application templates available from Microsoft through their “Microsoft.AspNetCore.SpaTemplates” package, including a template for Vue.js. This template works OK out of the box, but with a few small updates we can include some great material design components provided by Vuetify (https://vuetifyjs.com/) and hit the ground running.
Prerequisites
We’ll use Visual Studio 2017 in this example. You could also do this in Visual Studio Code if that is your preferred IDE. You need to be sure to have NodeJS/NPM installed as well (https://nodejs.org/en/download/). Finally, The “Vue.js Pack 2017” extension for Visual Studio offers better Vue snippets and intellisense: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.VuejsPack-18329
Get the SPA Templates
EDIT: Apparently Microsoft has ended support for their Microsoft.AspNetCore.SpaTemplates pack, which includes the vue template and is very disappointing. While it appears the dotnet new –install commands below still work, they may not forever. You can grab the vue template from our github here https://github.com/Dev-Squared/DotnetCoreVueSPATemplate and use it to complete the steps after this one. It appears MS also still has the template available in their ASPNet template repository: https://github.com/aspnet/templating/tree/dev/src/Microsoft.AspNetCore.SpaTemplates/content/Vue-CSharp. You can find more info here: https://github.com/aspnet/Announcements/issues/289
Vue Js Visual Studio 2019
The first thing you need to do is grab the SPA templates for ASP.NET Core 2. There are several great starter templates in here, including templates for React and Angular as well. To get the templates, open your favorite shell (I use Git Bash) and run the following:
dotnet new –install Microsoft.AspNetCore.SpaTemplates::*
This will result in all of the following templates being downloaded:
Now we’re ready to set up our sample Vue.js project. Navigate to where you want to store the project and create a folder for it. Then, from inside that folder, run the following command:
dotnet new vue
Just like that, you have a new ASP.NET Core 2/Vue.js application that you can open in Visual Studio.
Exploring the Template
The template creates a clean looking application with 3 navigation items in a navbar on the left:
The template uses Bootstrap 3 at the time of this writing. One of the things we will do later is update the template to use Vuetify components, which are Bootstrap 4 based.
One of the other nice things the template does for you is generate a webpack.config.json file. Webpack is kind of yucky, so this takes a lot of the work out of it for you. We won’t focus on how this functions in this post, but we will have to make one small tweak to it later to make Vuetify work. One of the nice things about the way this is set up though is that it does hot swapping – meaning the moment you change your Vue components, you can see that reflected on the page.
Finally, you can find the actual Vue components in the ClientApp –> components folder. There’s a separate folder for each component created as part of the template with a Vue html file and a TypeScript file:
Adding Vuetify Parker brothers monopoly game value.
Step 1: Add/update npm packages
There are several steps needed to get Vuetify up and running.
First, open up the package.json file and add the following packages:
“vuetify”: “^0.17.6”,
“stylus”: “^0.54.5”,
“stylus-loader”: “^3.0.1”
Here we add Vuetify, as well as stylus and stylus loader since Vuetify uses stylus.
Also, update the Vue package to the latest version (2.5.13 at the time of writing this), as Vuetify requires newer versions of Vue to work:
“vue”: “^2.5.13”,
Now, from your projects directory do an “npm install” to install the packages.
Step 2: Add style references and update webpack config
Next, we need to add a stylus file required by Vuetify. In the ClientApp folder, add a “stylus” folder. Inside of that folder, create a “main.styl” file. This file simply imports the main stylus from Vuetify for your app to use – you just need one line in the file:
@import ‘~vuetify/src/stylus/main’
Now, we need to modify the webpack config to use the stylus loader. In the webpack.config.js file at the root of the project, update the following from this:
To this:
Now we can properly compile the stylus elements of Vuetify.
We need to update the boot.ts file (the main typescript file for the Vue app) to use Vuetify and to point to the right styl file. Add the following to this file:
import ‘./stylus/main.styl’;
import Vuetify from ‘vuetify’;
Vue.use(Vuetify);
Vue Js W3schools
You can also remove the ‘import bootstrap’ line, since Vuetify is based on Bootstrap 4.
Finally, if you want to use the material icons built into Vuetify, add the following link to the top of your Views–>Home–>index.cshtml:
<link href=’https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons’ rel=”stylesheet”>
Now if you run the app, everything should work but look the same still. Next, we’ll add some of our fancy new components.
Step 3: Add Vuetify components
Before we can use any Vuetify components, we need to wrap our main app container in <v-app> tags. Navigate to ClientApp–>components–>app–>app.vue.html and put <v-app> tags inside the app-root div:
Now we can add Vuetify components to our other pages. The “Counter” page is a simple component that increments a counter when a button is clicked:
Adding a few Vuetify components to this page might spice it up:
Above we’ve added a v-alert component around the counter, as well as set the button’s class to “btn”. This results in the following:
This provides a great starting point to continue to add functionality to our SPA with the help of a great component library. There are lots of Vuetify components available – you can check them out here: https://vuetifyjs.com/components/alerts
You can also find the sample code from this post here: https://github.com/Dev-Squared/VuetifyDotnetCore2Sample
Are you using the right password manager for your agency?
Visual Studio Vue Js
ElePass is a password management solution built for agencies – developed by DevSquared. With security as the backbone, we built ElePass to drive agencies towards a more secure environment and to ensure your clients can trust you with their accounts. Check out some of the features of ElePass and give it a try today!