Hey!
In this article, I want to share my recent experiences with the Vue 3 Beta, and in particular some considerations you might want to take note of as you plan to migrate your existing Vue 2 applications to the upgraded version Vue 3!
The following list will help you move toward Vue 3 best practices and avoid some of the use cases that you might encounter when migrating from Vue 2 to Vue 3.
Let’s move on!
Avoid using the Vue event bus
Short summary: Do not use the \$ON /$once/$off API as it will be deprecated in Vue Company 3.
If you’ve heard of event bus, it’s a common term in Vue development when you come across situations where you need a shortcut for sending events from a child to a parent or from a child to a parent. You only have to search for “event event Bus” in your browser and you’ll find many articles describing it.
One thing to note is that this is not an official method recommended by Vue recommended. I say this because you will probably never see the Event Bus in the official Vue documentation. The closest reference comes from Vue 1.x’s migration guide, called “eventHub” here, which recommends that you switch to Vuex.
In simple cases, this pattern can replace $dispatch and $broadcast, but for more complex cases, a dedicated state management layer, such as Vuex, is recommended.
You can also check the RFC documentation to see why they don’t recommend it.
Because the event bus concept is really a publish-subscribe pattern, which is a common approach in programming, you can actually still use the concept, but with a different library like Mitt. 😉
Here is an example of the event bus and how to refactor it:
// Vue 2 example of event bus
import Vue from 'vue';
const eventBus = new Vue();
// subscribe
eventBus.$on('sandwich-made', () = >console.log('sandwich made! '));
// publish
eventBus.$emit('sandwich-made');
Copy the code
// Refactor to use 3rd party library like mitt
import mitt from 'mitt';
const eventBus = mitt();
// subscribe
eventBus.on('sandwich-made', () = >console.log('sandwich made! '));
// publish
eventBus.emit('sandwich-made');
Copy the code
Refactor the Filter function into Method
According to the RFC docs, the filter will be removed.
Filter is there to help you “format” your values, e.g., uppercase, add currency, short URL, etc. Perhaps it was also inspired by the Angular Filter. It looks good because you can implement it in template syntax. For example, here is a toCurrency filter that adds the currency format to the price integer value:
<div class="currency">{{ price | toCurrency }}</div>
Copy the code
Note: The price value is 25 and then filters the toCurrency to $25.00
Although it looks nice, keep in mind that it’s actually a “syntactic sugar” because at run time, toCurrency will always run to format the price whenever it updates the price.
If you refactor toCurrency as method instead, it would be written like this:
<div class="currency">{{ toCurrency(price) }}</div>
Copy the code
Refactoring in the Vue script simply moves the function from filter to method:
// before
{
filter: {
toCurrency (value) {
return ` $${value.toFixed(2)}`
}
}
}
// after
{
methods: {
toCurrency (value) {
return ` $${value.toFixed(2)}`
}
}
}
Copy the code
Cool! But what if you register the filter as a global filter?
Vue.filter('toCurrency'.function (value) {
return ` $${value.toFixed(2)}`
})
Copy the code
In this case, I recommend that you remove the global filter code above and move the filter functionality to a pure accessibility feature that can be shared first. Such as:
// helper/filter.js
export function toCurrency (value) {
return ` $${value.toFixed(2)}`
}
Copy the code
You can then import the helper function into the component that needs to use it. Such as:
// price-component.vue
import { toCurrency } from './helper/filter'
// your vue object
{
methods: {
toCurrency
}
}
Copy the code
Note: only toCurrency can be used;) Thanks to the shorthand for ES6 object properties
Refactor the component model to.sync
According to the RFC documentation, Vue 3 will deprecate the options in the modelVue component and replace sync with multiple Model.
If your Model uses options in the component to set two-way data binding, you can refactor it to.sync. Examples are as follows:
// BEFORE
// parent component
<child-component v-model="visible"/>
// the model option in the child component's Vue object
<script>
{
model: {
prop: 'visible'.
event: 'change'
}
}
</script>
Copy the code
Sync:
// AFTER
// parent component
<child-component v-bind:visible.sync="visible"/>
// delete the model option in the child component's Vue object
Copy the code
When you need to upgrade to Vue 3, you simply rename it to.sync.
// Vue 3
// parent component
<child-component v-model:visible="visible"/>
Copy the code
Easy squeeze lemon! 😋
Be wary of using third-party plug-ins
The beauty of the Vue framework, like other frameworks, is that it gives the community an API to create their own plug-ins.
In Vue 3, however, a major change will be made that will make some plug-ins no longer compatible. One major change is that plug-in installation and application initialization will remain unchanged from the original Vue instance. Such as:
BEFORE, in Vue 2
Vue.use(myPlugin);
new Vue({/* your vue initialization */});
// AFTER, in Vue 3
const app = createApp(); // new method to initialize Vue
app.use(myPlugin);
Copy the code
Most likely, the plug-in will not be able to refactor the code to use the plug-in in Vue 3 until its author upgrades it. Therefore, this means that if you plan to migrate, you should consider using a third-party plug-in, as this will become a blocker.
Check the issues or roadmap for the plug-ins you are using to see if they plan to upgrade to support Vue3. Here is an example of the plug-in that will support Vue 3:
- Bootstrap Vue
- Vue Multiselect
- Vuetify
If the plug-in you’ve used has no plans to upgrade to Vue 3, you can help by asking the issue’s author to support Vue 3 or even participate in the upgrade.
Write your components using @vue/composition-api
I would like to thank the Vue community for providing @vue/composition-api🥰. Not only does it allow developers to get their hands dirty using the Composition API, but it also provides the API that will be the core method in Vue 3.
For example, defineComponent. It will be the new standard for writing Vue components in Vue 3, and you can already use it in Vue 2 applications!
To use it, install @vue/ composition-API and replace the Vue object component to start. Such as:
// BEFORE
import Vue from 'vue';
export default Vue.extend({
name: 'my-component'.
/* your component props, data, methods, etc. */
});
Copy the code
Just replace it to use defineComponent:
// AFTER
import { defineComponent } from '@vue/composition-api';
export default defineComponent({
name: 'my-component'.
/* your component props, data, methods, etc. */
});
Copy the code
What’s the difference, you ask? Almost no difference, that’s the beauty of it! Your component should work as usual, and with “props” added, you can now refactor the component to use the Composition API if you wish:
// Refactor to use setup()
import { defineComponent } from '@vue/composition-api';
export default defineComponent({
name: 'my-component'.
setup (props) {
/* your component props, data, methods, etc. */
}
});
Copy the code
Note: If you like Typescript, I’m sure you’ll like the Composition API because it will help improve component input. 😉
More importantly
There will be another big change, such as:
- Render API changed
- Unifies scoped slots to slots only
- The keyCode modifier to remove
- The inline template will be deleted
However, if you don’t use it very often and you think you can easily refactor it, it depends on whether you decide to make the change sooner or later.
Abstract
I hope this article has helped you prepare for the upgrade to Vue 3. As a Vue developer, I’m happy to see it coming because it uses better apis to handle reactivity, more Typescript support, and better practices in development.
Please let us know if I missed any APIS or instructions to define and thank you for your feedback. Thanks, have a nice day!