1605172526
This article will introduce you to new features and paradigms introduced in Vue 3 and demonstrate how you can leverage the new Composition API to improve code expressiveness, as well as code organization and reuse.
Apart from admirable performance improvements, the recently released Vue 3 also brought several new features. Arguably the most important introduction is the Composition API. In the first part of this article, we recap the standard motivation for a new API: better code organization and reuse. In the second part, we will focus on less-discussed aspects of using the new API, such as implementing reactivity-based features that were inexpressible in Vue 2’s reactivity system.
We will refer to this as on-demand reactivity. After introducing the relevant new features, we will build a simple spreadsheet application to demonstrate the new expressiveness of Vue’s reactivity system. At the very end, we will discuss what real-world use this improvement on-demand reactivity might have.
Vue 3 is a major rewrite of Vue 2, introducing a plethora of improvements while retaining backward compatibility with the old API almost in its entirety.
One of the most significant new features in Vue 3 is the Composition API. Its introduction sparked much controversy when it was first discussed publicly. In case you are not already familiar with the new API, we will first describe the motivation behind it.
The usual unit of code organization is a JavaScript object whose keys represent various possible types of a piece of a component. Thus the object might have one section for reactive data (data
), another section for computed properties (computed
), one more for component methods (methods
), etc.
Under this paradigm, a component can have multiple unrelated or loosely related functionalities whose inner workings are distributed among the aforementioned component sections. For example, we might have a component for uploading files that implements two essentially separate functionalities: file management and a system that controls the upload status animation.
The <script>
portion might contain something like the following:
export default {
data () {
return {
animation_state: 'playing',
animation_duration: 10,
upload_filenames: [],
upload_params: {
target_directory: 'media',
visibility: 'private',
}
}
},
computed: {
long_animation () { return this.animation_duration > 5; },
upload_requested () { return this.upload_filenames.length > 0; },
},
...
}
There are benefits to this traditional approach to code organization, mainly in the developer not having to worry about where to write a new piece of code. If we’re adding a reactive variable, we insert it in the data
section. If we’re looking for an existing variable, we know it must be in the data
section.
This traditional approach of splitting the functionality’s implementation into sections (data
, computed
, etc.) is not suitable in all situations.
The following exceptions are cited often:
Vue 2 (and the backward-compatible Vue 3) offer a solution to most of the code organization and reuse issues: mixins.
Mixins allow the functionalities of a component to be extracted in a separate unit of code. Each functionality is put in a separate mixin and every component can use one or more mixins. Pieces defined in a mixin can be used in a component as if they were defined in the component itself. The mixins are a bit like classes in object-oriented languages in that they collect the code related to a given functionality. Like classes, mixins can be inherited (used) in other units of code.
However, reasoning with mixins is harder since, unlike classes, mixins need not be designed with encapsulation in mind. Mixins are allowed to be collections of loosely bound pieces of code without a well-defined interface to the outer world. Using more than one mixin at a time in the same component might result in a component that is difficult to comprehend and use.
Most object-oriented languages (e.g., C## and Java) discourage or even disallow multiple inheritance despite the fact that the object-oriented programming paradigm has the tools to deal with such complexity. (Some languages do allow multiple inheritance, such as C++, but composition is still preferred over inheritance.)
A more practical issue that may occur when using mixins in Vue is name collision, which occurs when using two or more mixins declaring common names. It should be noted here that if Vue’s default strategy for dealing with name collisions is not ideal in a given situation, the strategy can be adjusted by the developer.This comes at the cost of introducing more complexity.
Another issue is that mixins do not offer something akin to a class constructor. This is a problem because often we need functionality that is very similar, but not exactly the same, to be present in different components. This can be circumvented in some simple cases with the use of mixin factories.
Therefore, mixins are not the ideal solution for code organization and reuse, and the larger the project, the more serious their issues become. Vue 3 introduces a new way of solving the same issues concerning code organization and reuse.
The Composition API allows us (but does not require us) to completely decouple the pieces of a component. Every piece of code—a variable, a computed property, a watch, etc.—can be defined independently.
For example, instead of having an object that contains a data
section that contains a key animation_state
with the (default) value “playing,” we can now write (anywhere in our JavaScript code):
const animation_state = ref('playing');
The effect is almost the same as declaring this variable in the data
section of some component. The only essential difference is that we need to make the ref
defined outside of the component available in the component where we intend to use it. We do this by importing its module to the place where the component is defined and return the ref
from the setup
section of a component. We’ll skip this procedure for now and just focus on the new API for a moment. Reactivity in Vue 3 doesn’t require a component; it’s actually a self-contained system.
We can use the variable animation_state
in any scope that we import this variable to. After constructing a ref
, we get and set its actual value using ref.value
, for example:
animation_state.value = 'paused';
console.log(animation_state.value);
We need the ‘.value’ suffix since the assignment operator would otherwise assign the (non-reactive) value “paused” to the variable animation_state
. Reactivity in JavaScript (both when it is implemented through the defineProperty
as in Vue 2, and when it’s based on a Proxy
as in Vue 3) requires an object whose keys we can work with reactively.
Note that this was the case in Vue 2, as well; there, we had a component as a prefix to any reactive data member (component.data_member
). Unless and until the JavaScript language standard introduces the ability to overload the assignment operator, reactive expressions will require an object and a key (e.g., animation_state
and value
as above) to appear on the left-hand side of any assignment operation where we wish to preserve reactivity.
In templates, we can omit .value
since Vue has to preprocess the template code and can automatically detect references:
<animation :state='animation_state' />
In theory, the Vue compiler could preprocess the <script>
portion of a Single File Component (SFC) in a similar way, too, inserting .value
where needed. However, the use of refs
would then differ based on whether we are using SFCs or not, so perhaps such a feature is not even desirable.
Sometimes, we have an entity (for example, be a Javascript object or an array) that we never intend to replace with a completely different instance. Instead, we might only be interested in modifying its keyed fields. There is a shorthand in this case: using reactive
instead of ref
allows us to dispense with the .value
:
const upload_params = reactive({
target_directory: 'media',
visibility: 'private',
});
upload_params.visibility = 'public'; // no `.value` needed here
// if we did not make `upload_params` constant, the following code would compile but we would lose reactivity after the assignment; it is thus a good idea to make reactive variables ```const``` explicitly:
upload_params = {
target_directory: 'static',
visibility: 'public',
};
Decoupled reactivity with ref
and reactive
is not a completely new feature of Vue 3. It was partly introduced in Vue 2.6, where such decoupled instances of reactive data were called “observables.” For the most part, one can replace Vue.observable
with reactive
. One of the differences is that accessing and mutating the object passed to Vue.observable
directly is reactive, while the new API returns a proxy object, so mutating the original object will not have reactive effects.
What is completely new in Vue 3 is that other reactive pieces of a component can now be defined independently too, in addition to reactive data. Computed properties are implemented in an expected way:
const x = ref(5);
const x_squared = computed(() => x.value * x.value);
console.log(x_squared.value); // outputs 25
Similarly one can implement various types of watches, lifecycle methods, and dependency injection. For the sake of brevity, we won’t cover those here.
Suppose we use the standard SFC approach to Vue development. We might even be using the traditional API, with separate sections for data, computed properties, etc. How do we integrate the Composition API’s small bits of reactivity with SFCs? Vue 3 introduces another section just for this: setup
. The new section can be thought of as a new lifecycle method (which executes before any other hook—in particular, before created
).
Here is an example of a complete component that integrates the traditional approach with the Composition API:
<template>
<input v-model="x" />
<div>Squared: {{ x_squared }}, negative: {{ x_negative }}</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
name: "Demo",
computed: {
x_negative() { return -this.x; }
},
setup() {
const x = ref(0);
const x_squared = computed(() => x.value * x.value);
return {x, x_squared};
}
}
</script>
Things to take away from this example:
setup
. You might want to create a separate file for each functionality, import this file in an SFC, and return the desired bits of reactivity from setup
(to make them available to the remainder of the component).x
, even though it’s a reference, does not require .value
when referred to in the template code or in traditional sections of a component such as computed
.#vue #javascript #programming #web-development #developer
1600583123
In this article, we are going to list out the most popular websites using Vue JS as their frontend framework.
Vue JS is one of those elite progressive JavaScript frameworks that has huge demand in the web development industry. Many popular websites are developed using Vue in their frontend development because of its imperative features.
This framework was created by Evan You and still it is maintained by his private team members. Vue is of course an open-source framework which is based on MVVM concept (Model-view view-Model) and used extensively in building sublime user-interfaces and also considered a prime choice for developing single-page heavy applications.
Released in February 2014, Vue JS has gained 64,828 stars on Github, making it very popular in recent times.
Evan used Angular JS on many operations while working for Google and integrated many features in Vue to cover the flaws of Angular.
“I figured, what if I could just extract the part that I really liked about Angular and build something really lightweight." - Evan You
#vuejs #vue #vue-with-laravel #vue-top-story #vue-3 #build-vue-frontend #vue-in-laravel #vue.js
1597416091
Vue Router helps developers easily build single page applications with Vue.js. This video uses a simple e-Commerce application as an example to show how routing works in Vue 3 with vue-router. This video also shows how to initialize vue-router, dynamically load routes, breaks down the benefits and differences between useRoute and useRouter, and more.
Vue Router is a powerful tool, enabling nested route/view mapping, modular component-based router configuration, router params, query, and wildcards, view transition effects, fine-grained navigation control, integration with automatic active CSS classes, HTML5 history mode or hash mode with auto-fallback in Internet Explorer 9, and customizable scroll behavior. Learn more about vue-router and take a look at the source code on Github: https://github.com/vuejs/vue-router
#vue #vue 3 #vue router #programming
1596114720
Vue 3 has not been officially released yet, but the maintainers have released beta versions for us punters to try and provide feedback on.
If you’re wondering what the key features and main changes of Vue 3 are, I’ll highlight them in this article by walking you through the creation of a simple app using Vue 3 beta 9.
I’m going to cover as much new stuff as I can including fragments, teleport, the Composition API, and several more obscure changes. I’ll do my best to explain the rationale for the feature or change as well.
We’re going to build a simple app with a modal window feature. I chose this because it conveniently allows me to showcase a number of Vue 3 changes.
Here’s what the app looks like in it’s opened and closed states so you can picture in your mind what we’re working on:
Rather than installing Vue 3 directly, let’s clone the project vue-next-webpack-preview
which will give us a minimal Webpack setup including Vue 3.
$ git clone https://github.com/vuejs/vue-next-webpack-preview.git vue3-experiment
$ cd vue3-experiment
$ npm i
Once that’s cloned and the NPM modules are installed, all we need to do is remove the boilerplate files and create a fresh main.js
file so we can create our Vue 3 app from scratch.
$ rm -rf src/*
$ touch src/main.js
Now we’ll run the dev server:
$ npm run dev
Straight off the bat, the way we bootstrap a new Vue app has changed. Rather than using new Vue()
, we now need to import the new createApp
method.
We then call this method, passing our Vue instance definition object, and assign the return object to a variable app
.
Next, we’ll call the mount
method on app
and pass a CSS selector indicating our mount element, just like we did with the $mount
instance method in Vue 2.
src/main.js
import { createApp } from "vue";
const app = createApp({
// root instance definition
});
app.mount("#app");
With the old API, any global configuration we added (plugins, mixins, prototype properties etc) would permanently mutate global state. For example:
src/main.js
// Affects both instances
Vue.mixin({ ... })
const app1 = new Vue({ el: '#app-1' })
const app2 = new Vue({ el: '#app-2' })
This really shows up as an issue in unit testing, as it makes it tricky to ensure that each test is isolated from the last.
Under the new API, calling createApp
returns a fresh app instance that will not be polluted by any global configuration applied to other instances.
Learn more: Global API change RFC.
#vue.js #components #composition api #design patterns #vue 3 #vue
1597075980
One of the features of Vue that first hooked me and many other developers is its reactivity system.
It’s not just the ease in which it allows you to build dynamic UIs, but the fact that it just works without you having to think about it or even understand it.
If you want to become a more advanced Vue developer, however, and especially if you want to use advanced features like the Composition API, it’s important to have some level of understanding of how reactivity works under the hood.
In this article, I’ll tell the story of why reactivity was created, how it works in Vue 2, and how it’s evolved to support powerful Vue 3 features like the Composition API.
On day #1 of using Vue, the feature that will probably stand out to you most is how effortless it is to get Vue to link a JavaScript data model to the rendered page.
When you then modify that data during the app lifecycle, like magic, the UI you’ve created from this data will be updated, too.
For example, say you’ve got a data property message
in a Vue component and you’re rendering this message in the view with a text interpolation:
Vue.component("my-component", {
data: {
message: "Hello, world"
},
template: "<p>{{ message }}</p>"
});
This is what will be rendered when the app instantiates:
<p>Hello, world</p>
What will happen when you modify message
during the app lifecycle, for example, in a method?
methods: {
updateMessage () {
this.message = "Goodbye, world";
}
}
Vue will automatically update the view to reflect this:
<p>Goodbye, world</p>
Even though this usage of reactivity is one of the key feature of Vue.js, it is actually just one possible use.
Reactive data can be more broadly thought of as data that causes some intended side effect when accessed or modified.
The intended side effect may be an update of the DOM, the re-calculation of a computed property, or some custom functionality that the developer provides.
If the success of Vue had to be attributed to just one thing, I’d wager it’s the fact that you can use it to build a robust reactive UI without understanding a thing about how reactivity works.
However, if you want to become an advanced Vue developer, understanding more about reactivity will allow you to:
To begin this understanding, we need to be aware of the JavaScript features that underpin reactivity.
Did you know that you can alter the way a JavaScript object is written or read? This can be done by providing a custom get
or set
method for that object.
For example, if you wanted to automatically console log the value of an object any time its modified, you could do that by defining a custom set
method (aka “setter”).
const obj = {
value: "Hello, world",
set message (newVal) {
this.value = newVal;
console.log(newVal);
}
get message () {
return this.value;
}
};
obj.message = "Goodbye, world";
// console: Goodbye, world
Instead of logging to the console, what if we used the setter to update the DOM? This is the mechanism that allows reactivity to work.
#vue.js #reactivity #composition api #design patterns #components #vue
1603374000
Evan You is an independent software developer and the creator of the open source JavaScript framework Vue.js. We had a chance to speak to Evan about the release of Vue 3, his opinion on no-backend & fullstack approaches, Vue.js use cases and the work-life balance of the creator of the technology.
The Interview
Evrone: Hey Evan, it’s great having you here today! Let’s start our interview with such a question: your Patreon-funded full-time job position is quite unique. How do you organize your work-life balance and avoid burnouts?
Evan: I try to follow a fixed schedule every day even though I’m self-employed and working from home. Having kids actually helps a lot in this regard because I get to (and have to) spend time with family whenever I’m not working. Another important thing is that I take long breaks (several weeks) whenever I feel I need to — which is probably harder to do if I’m a full time employee at a company.
Evrone: Great!Vue 3 release is around the corner. Will you take a break after it or do you already have plans for the next version of the new Vite build system?
Evan: I always have a long backlog. For Vite, the current goal is actually just making it more stable — it’s a new system and people are trying to use it in scenarios that I didn’t initially design for, so we will give it some time to see where it should evolve next. There are also already ideas lined up for Vue 3.1. But I will definitely take a break, it’s important to recharge!
#vuejs #vue #vue-3 #vue.js #build-vue-frontend #angular