Compiling Vue 3 from scratch and trying the new Composition API

Lachlan Miller
Nov 14, 2019 · 6 min read
Image for post
Image for post
Try Vue 3 RIGHT NOW — by compiling it from scratch using the vue-next repo!

In this article I’ll compile Vue 3 from the latest source and try out some of the new APIs, include the upcoming composition API, all using TypeScript.

This is the app we will be building:

Image for post
Image for post
The final app I will build

I’ll also give my opinions on the new composition API after trying it out. You can read the RFC here. The source code for this article is here. Since Vue 3 is still under active development, and not even available on npm yet, some features and APIs may change — this article reflects the current state as of the 14th of Nov, 2019.

Image for post
Image for post
Check out my Vue.js 3 course! We cover the Composition API, TypeScript, Unit Testing, Vuex and Vue Router.

Getting and Compiling Vue 3

Next, add a basic index.ts:

And index.ts:

Since we will use TypeScript, we will need a few dependencies and a basic webpack.config.js to compile for use in a browser. Install them:

We need -W since we are currently are in a git repository containing several sub packages (in the packages directory, Vue 3 is very modular like that) and we want to install the dependencies to the top level. We will piggyback of the existing tsconfig.json - but we don't want to watch the entire repository during development, since we have already built the project when we ran yarn build earlier. In the existing tsconfig.json, remove all the entires in the "include" array.

Next, I created a webpack.config.js and added the following:

Okay, now we are ready to start hacking. I had bit of trouble getting everything to work — I was really hoping to import a bunch of TypeScript methods and get autocompletion out of the box, but either I didn’t build the packages right or I’m missing something, or it’s just too early for that in development of Vue 3. So we will need some type definitions. The TypeScript experience is, to me, the killer feature of Vue 3, not the new APIs or other features.

Building an App with Vue 3 and TypeScipt

I tried using the definitions generated during the yarn build step earlier, but I couldn't get it working - TS errors everywhere, so for now I just made some minimal types to get us started. We no longer do const app = new Vue(....).$mount('#app') anymore - Vue 3 exposes a createApp function, which returns a mount method to which you pass your root component and selector.

Ideally, we would use tsx in render functions, however I couldn't get that working either, so for now I'll just use string literals with template. In the future, tsx and render functions will be supported, and we should be able to get static typechecking on our templates, like in React when using tsx!

You can see there is now a setup function, which takes the props as the first argument, as shown in the Info component. Since App is the top level component, it does not receive any props. setup returns and object which is what would be saved in data and computed fields in the current Vue 2 API. This will still be an option in Vue 3, as well.

Whatever you return from setup are made available in the template function. I like to define this object as XXXSetup, where XXX is the name of component. It's like a schema for your component; it tells the developer what the setup function's API looks like. Think of it like a form a documentation.

setup is called once, when the component is created for the first time (like the existing created lifecycle method). The above code renders the following entirely uninteresting Vue app:

Image for post
Image for post

Let’s explore some more of the new APIs.

Using reactive

We can update the setup function in App using the new reactive function. reactive takes an object - count is a primitive. You can use another new API, ref, for primitive values, but for now let's use reactive with a count key. This will make it easy to add more reactive properties soon. They are actually slightly difference, you can read more here in the RFC.

Next, update Info to use the new increment function:

Errata: you do not need to return props . Vue automatically makes them available in the template.

Let’s say we want the message prop to be dynamic, based on the value of count. We can use computed. Update the type definition, which in it's basic form is the same as reactive. Also update App:

Image for post
Image for post

Now we have two count messages that increment together. Let’s take a look at another familiar API from Vue 2, watch. There are quite a few type overloads if you dig deep into the repo, I'll just demonstrate the simplest here.

Final type definitions for this article
Final App

watch, takes a function, which should reutrn the reactive object to watch. The next argument is a callback which is called when the watched value mutates. The callback receives the newly updated value and the previous value, just as it does in Vue 2.

Image for post
Image for post
The final app

This is a pretty basic app, but it does a good job of showing of the new Vue 3 composition API.

Thoughts and Reflection

  • The entire codebase is in TypeScript, which means we get better type checking and assistance from the IDE.
  • The composition API allows for better Typescript support. I think this is the real killer feature — I don’t have a strong opinion on which API I like better, I just want to have type safety so I can build bug free applications and deliver value to clients.
  • It is certainly a departure from what I first liked about Vue — simple and seemingly “magic” reactivity.
  • Good support for tsx - not my preferred way to write templates, but if it means better type safety, I'll take it.

Some of the cons are:

  • Two ways to write Vue components — just because you know one Vue app well, another might be completely different. This is kind of how I feel about React now. Some codebases use class component with lifecycle methods, and other use function components with the new React hooks. It's a bit tiring to learn so many ways to do the same thing.
  • likely more work to write a plugin supporting two different APIs.
  • You need to learn something new. If you don’t like learning new things, you probably don’t belong in the modern JS world anyway. Not sure if this is a good or bad thing 🤷‍♂

Conclusion

For more learning resources, I’ve found Vue School to have the best courses. The teachers, Alex and Chris, are core contributors to Vue and the upcoming Vue 3, and have been for many years.

Image for post
Image for post
https://vueschool.io/?friend=vth

They were a big help to me when learning Vue. They also have an upcoming Vue 3 master class which I’m looking forward to. Alex mentioned they have a big sale coming up for Black Friday, so check their courses out if you looking for more Vue resources.

Originally posted on my personal blog.

Vue.js Developers

Helping web professionals up their skill and knowledge of…

Lachlan Miller

Written by

I write about frontend, Vue.js, and TDD on https://vuejs-course.com. You can reach me on @lmiller1990 on Github and @Lachlan19900 on Twitter.

Vue.js Developers

Helping web professionals up their skill and knowledge of Vue.js

Lachlan Miller

Written by

I write about frontend, Vue.js, and TDD on https://vuejs-course.com. You can reach me on @lmiller1990 on Github and @Lachlan19900 on Twitter.

Vue.js Developers

Helping web professionals up their skill and knowledge of Vue.js

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store