5 Reasons Why Portugal is the Perfect Location for Nearshore Development

Portugal has long been a popular destination for tourists, but in recent years it has also become a top choice for businesses looking to establish a Nearshore development center. In this blog post…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Discovering Vue Composition API with Examples

A fresh, more functional alternative to the standard Options API

Vue 3 is the next major iteration of the highly popular JS UI framework. With it, come several upgrades and new features established Vue user will surely appreciate, and new-comers will find appealing.

The two biggest ones worth mentioning are improved TypeScript support (Vue 3 has been rewritten from ground-up in TypeScript) and Composition API — a fresh, more functional alternative to standard Options API.

In this tutorial, we’ll explore both of these features, in practice, by building the industry-standard example for UI framework demos — a simple TODO app!

Go to your terminal, ensure you’re on Node.js v12 or later, and run:

Or if you’re using Yarn:

When prompted, type in the name of your project, choose Vue as the framework, and TypeScript as the template variant.

Now, open the project, install dependencies, run the dev command, and let’s get to work!

I’ve added an example TODO item to preview the markup. The end result should look somewhat like this:

Vue 3 TODO app preview

Now we can work on adding some reactivity!

In Vue Composition API, the main ingredient of reactivity is a ref. It’s created using the ref() function, which wraps the provided value and returns the corresponding reactive object. You can later use the object to access its value through value property.

ref(), like any other part of Composition API, should be used in the setup() method. So, let’s go in there and create a ref to hold our TODO input value.

You can see that we return the input ref from the setup(). That’s required to access it in the template, which we’ll do, to pass it to the TODO <input/> v-model.

Now input will hold the current TODO value! We’ll use that more in a bit.

With input handled, we should move on to collecting and displaying actual TODOs. To do that, we’d need 2 refs — one for active and one for inactive TODOs. But why use 2 and split the data that should be kept together if we don’t have to?

Instead of ref(), we can use reactive(). This function makes a reactive copy of the whole passed object. It also has the added benefit of not having to use .value to access the reactive wrapper’s value. Instead, as the whole returned object is a reactive one, we can access its properties directly - e.g., reactiveObject.property.

So, let’s use reactive() in our setup() and render some actual TODOs!

You can see that our setup() got a bit more crowded, but it’s still pretty simple. We just added our reactive todos (with some sample ones) and some functions to control them. Also, notice the new TypeScript interfaces and randomId() utility function - IDs are required to differentiate TODOs with the same text.

As for how it all looks in our template:

With these edits, our TODOs can now be controlled through their buttons, but we still need to handle adding new TODOs.

With our current knowledge of Vue template syntax, ref() and reactive(), implementing TODO adding functionality shouldn’t be a problem. We’ll handle it by listening to Enter key on our input field.

First, some TS:

And then, to use our handleEnter() function in the template:

Now our TODO app is pretty much functional. You can add, remove, complete, and restore TODOs — all with just one ref() and one reactive() - amazing!

Now, if we were just making a simple app, we could stop right here, but that’s not what we’re after. We want to learn Composition API in practice, so let’s carry on!

How about adding a counting functionality to count active, completed, and all TODOs? We could do this with just length, but maybe we should do something more interesting?

Numbers of active and completed TODOs separately are easily accessible through their respective lengths, so let’s instead focus on the number of all TODOs. For that, we’ll use one new ref and another function of Composition API - watch().

watch() is an alternative to the watchers from Options API watch property (as pretty much all of the Composition API is - just a different, better way to do the same thing). It allows you to watch the selected reactive objects (refs or reactives) and react to the changes. We’ll use it to watch todos and update new todosCount ref.

Notice the watch() syntax. First comes the watched reactive value (or an array of reactive values). Then, the most important part - the callback function, which receives unwrapped values that were updated (i.e., no need to use .value if we’re watching refs), and also previous values (not needed in our case). Lastly, there’s the options object that configures the behavior of watch(). Here, we’re passing immediate flag to have our callback run immediately after watch() call to populate todosCount before initial rendering.

Now return todosCount from setup() and use it in the template. For example:

The thing to note here is that inside the template, all the refs returned from the setup() are automatically unwrapped (or specifically handled, e.g., in case of using them with v-models), so no .value access is required.

Alright, so our counter is working, but it’s not very elegant. Let’s see how we can make it cleaner with computed()!

Like watch(), computed() is similar to Options API computed property. It’s like a basic ref, but with advanced getter and optional setter functionality.

In our case, all we need is a getter, so we can make use of shorthand, and in result, shorten our previous code to something like this:

Now, the code is much cleaner, and the template stays the same.

A word of caution, though — computed() isn’t necessarily better than watch(). It’s just that they’re good for different tasks. Do you want to compute one value based on other reactive ones? Use computed(). Just want to react to value change? Use watch(). The example above is just an example guide to how to use them.

To demonstrate other parts of Composition API, we’ll have first to organize our code a bit.

Let’s split out the Todo and DoneTodo components. For the first one:

And for the DoneTodo:

​​Now, there’s a bit of repetition between both of these components, but for the sake of example, to recreate multi-component workflow, let’s keep them like that.

So, in a normal project, you’d have a lot of components. In such an environment, you’ll eventually have to share a value between them all — something like color theme, user details, etc. Passing props so many levels deep would be rather tedious. That’s where provide() and inject() come in.

With provide() you can serve the specified value multiple levels down the child tree, to then use inject(), to access and use these values in any of the child components.

So, provide() and inject() are often used for configuring a theme, like enabling or disabling dark mode. In our case, we could simply use a CSS class flag, but more often than not, a theme value is controlled or required by the JS code. So, let’s implement a simple dark mode toggle in our TODO app, using provide() and inject()!

Inside setup(), we create the darkMode ref, define a function for toggling it, and provide() the ref for later injection in child components. Notice how we provide a ref - it’s required to preserve reactivity in child components. However, remember that updating the ref value from child components which it was injected to is discouraged. Instead, just provide additional mutation function to handle it properly.

Then, in the main component’s template, we set the dark class name accordingly (additional CSS setup required).

As for child components like Todo or DoneTodo, here we’ll have to use inject().

So, we inject() the ref and return it from setup(). Then in the template, we can use the injected ref like any other.

The same can be done for the other child component.

With dark mode applied and working properly, our end result should look somewhat like this:

OpenReplay lets you reproduce issues, aggregate JS errors and monitor your app’s performance. We offer plugins for capturing the state of your Redux or VueX store and for inspecting Fetch requests and GraphQL queries.

OpenReplay

I hope this little app and tutorial showed you how different bits of the new Vue Composition API fit together. We’ve only explored the essential bits, but as long as you know how they interact with each other to form something bigger, you’ll easily use other parts of the API, like template refs, shallow refs, watchEffect(), etc.

Also, remember that the biggest feature of the Composition API is that it’s composable, meaning you can easily extract different parts of code to separate functions. This in turn makes your code cleaner and increases readability.

Add a comment

Related posts:

The Message Girls and Young Women Need to Hear About Aging

In her book The Genius of Women: From Overlooked to Changing the World, which highlights the achievements of women who have long been ignored, undermined, and overlooked, author Janice Kaplan wonders…

Proper Ways of Choosing Best Ground Coffee

When people say they cannot stand coffee because it is tasteless or too bitter or tart, I feel like saying: you simply don’t know how to prepare it the right way! But even the most experienced coffee…

I Visited the Louvre Yesterday

A story told in pictures. “I Visited the Louvre Yesterday” is published by Stephen M. Tomic in Scene & Heard (SNH).