Let’s use Vue3 Features in Your Vue2 Project

Chamara Senarath
Ascentic Technology
6 min readAug 8, 2022

--

I have been working on a Vue 2 project for a long time. When I heard the news “Vue 2.7 Released”, I seriously wanted to upgrade our project considering the features they have backported from Vue 3. The backported features are:

  • Composition API
  • SFC :<script setup>
  • SFC : CSS v-bind

In this article, I will show you, how to upgrade your existing Vue2 project to Vue 2.7 and I will explain how to use the mentioned backported features in your project explaining a small application.

Upgrade Guide.

  1. Upgrade local @vue/cli-xxx dependencies.
npm update -g @vue/cli
# OR
yarn global upgrade --latest @vue/cli

2. Remove node_modules folder and the lockfile (package-lock or yarn.lock) and perform a fresh install.

3. If you were previously using @vue/composition-api or
vue-template-compiler, uninstall them and update the places where you use imports from @vue/composition-api to vue.

4. If you run into unused variable lint errors when using <script setup>, update eslint-plugin-vue to the latest version (9+)

5. If you are using webpack, make sure to include VueLoaderPlugin in your webpack config file

// webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
module: {
rules: [
// ...rules
]
},
plugins: [
// make sure to include the plugin!
new VueLoaderPlugin()
]
}

Using backported features

Now, you are ready to use amazing backported features from Vue 3. Let’s create a small application using the mentioned features. The application is Free Fuel Pass. Imagine you are given a limited amount of free fuel for a week from the government. There is a pass (QR Code) you have to show to your filling station then you can click the Fill Me Up button in your application and you get 1L per click. You can see the eligible weekly quota and the balance is updated each time you press the button.

Step 1 — Setting up the environment

  • Since we are creating a new application, you can use your Vue-CLI to create a new project. Enter the following command and select Vue 2
  • Upgrade your project to vue 2.7 as mentioned in the upgrade guide.

Step 2 — Get your hands dirty with vue

I have created this application to give you as many examples of backported features as possible in a single application.

Starting with our App.vue file.

Just like any other vue file, we have <template>, <script> and <style> sections here. Let’s have a look at the things we have used here. In the template, we have the application title, quota view, and fill me up button. QuotaView and FillMeUp components are imported from the components folder.

QuotaView expects 2 props, which are eligible quota and used quota. Notice how we access them using <script setup>. we are using Vue3’s reactivity to create these two variables. There are two ways you can define a reactive variable in Vue3 (Composition API). You can use reactive or ref methods. There is a difference in using them and we will keep it to discuss in another article. Here, we have assigned 0 to both eligibleQuota and usedQuota variables.

FillMeUp expects 1 prop, which is disabled and it emits click-fill when you click on the button. To handle the click-fill event, we have created handleOnClickFill function and it expects the payload from the click-fill event. In the function, we simply check if the usedQuota value is greater than or equal to eligibleQuota and set isDisabledFill variable to true, and returns from the function if the condition is true. Otherwise, the amount is added to usedQuota. Since we are using ref, you need to include “.value” to read or write from/to a reactive variable inside the script. But, inside the <template>, you can use reactive variables just like you used to do it in vue2 (just by calling the variable name)

Now, we need to set a random value to our eligibleQuota’s value. So, the best place to do so is inside onMounted lifecycle hook. We are assigning a value between 5 to 25 to eligibleQuota.

Wait... What about the <style>?? Sorry, I am not going to explain them here as there is no change in using CSS in Vue 2.7 😉. But I will explain CSS V-bind in the next section.

Fill Me Up

Here, there is only one element in the template, which is our button. button has “fill-me-button” class and it calls handleOnClickFill function on click. As we discussed earlier, this component expects disabled prop, which is defined inside defineProps method. You can pass multiple objects into the defineProps method if you have multiple props. We have assigned this to props constant in order to access props inside the script. If you are not accessing props inside the script, you can ignore assigning this since you can access props inside the template just by calling the name of the property.

When you click on the button, it fires handleOnClickFill function. Inside the function, we emit ‘click-fill’ event with a payload, which is {amount:1} object. In order to use this emit, first, we have to register it. That’s where the defineEmits method comes into the picture. Similar to props, you can ignore assigning this to a constant if you only using it inside the template. defineEmits method expects an array of strings. Since we have only one event. let’s register it using its name (‘click-fill’).

We are using ‘disabled’ prop to generate a string to buttonCursor variable. Since we are generating a text, based on another variable (prop), let’s use the computed function. so, if the disabled prop is true, it returns ‘not-allowed’ and if not, it returns ‘pointer’

Now, let’s see how we can use CSS v-bind. Inside the <style>, we are using v-bind to change the button’s cursor based on the value of the buttonCursor variable.

Quota View

This is the simplest component of our project. It expects two props, eligibleQuota, and usedQuota. There is a computed function to calculate the balance quota based on the props and the result is assigned to the balanceQuota variable. In the template, it shows the eligible weekly quota and the balance weekly quota.

So, we have covered how to use reactive variables, define props, define emits, computed properties, lifecycle hooks, and CSS v-bind. but there is one missing part. Now, we know how to replace “this.$emit” with defineEmit. But do you know how to replace “this.$router”? or other properties you used to access with “this” such as prototypes? This is something I struggled to find when working on my project. The best way I found was, to extract these from your current instance’s proxy. Just like this

Here I have extracted route, router, and http. Now, you can easily use these in your script.

I believe you have learned how to upgrade your project to Vue 2.7 and how to use the features in your project. You can find the application code on my Github account: https://github.com/chamara-senarath/free-fuel-pass-example. Follow me for more articles. ✌️

--

--