Our Global Presence
Canada
57 Sherway St,
Stoney Creek, ON
L8J 0J3
India
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
USA
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
Vue 3 isn’t officially released yet, but the Vue team has released the Alpha version to use some of the features that will be shipped with Vue 3.
We’ll use the WebPack-based setup.
To do this, clone this repository:
git clone https://github.com/vuejs/vue-next-webpack-preview.git vue-next cd vue-next
Now install the packages:
npm install
That’s it. We have a working Vue 3 project set up now.
To spin up the application, just run the following:
npm run dev
Open localhost:8080
in your browser, and you can see a simple counter application.
Open the package.json
file, you can see the Vue version here. At the time of writing this article, the version is 3.0.0-alpha.8
.
Open App.vue
and you’ll see the setup()
method, i.e. the Composition API already being used here. We might see some lint errors from Vue’s official plugin, eslint-plugin-vue
, because the linters are not yet updated to understand the new syntax.
Before we start coding, let’s go over the new features in Vue 3.
Vue 3 is faster, smaller in file size, and equipped with better TypeScript support. Some of the new features that we can discuss and learn to implement in this article include:
Composition API was launched as a plugin a few months back, so there is nothing new there, but in Vue 3 we don’t have to install it like a plugin anymore. Now, it’s built into the package and can be used out of the box without any additional setup.
There are two main advantages to using the Composition API:
If you are new to Composition API, here is how we can use it to implement a component:
<template> <div class="counter"> <p>count: {{ count }}</p> <p>NewVal (count + 2): {{ countDouble }}</p> <button @click="inc">Increment</button> <button @click="dec">Decrement</button> <p> Message: {{ msg }} </p> <button @click="changeMessage()">Change Message</button> </div> </template> <script> import { ref, computed, watch } from 'vue' export default { setup() { /* ---------------------------------------------------- */ let count = ref(0) const countDouble = computed(() => count.value * 2) watch(count, newVal => { console.log('count changed', newVal) }) const inc = () => { count.value += 1 } const dec = () => { if (count.value !== 0) { count.value -= 1 } } /* ---------------------------------------------------- */ let msg= ref('some text') watch(msg, newVal => { console.log('msg changed', newVal) }) const changeMessage = () => { msg.value = "new Message" } /* ---------------------------------------------------- */ return { count, inc, dec, countDouble, msg, changeMessage } } } </script>
And here’s the equivalent code in Options API:
<template> <div class="counter"> <p>count: {{ count }}</p> <p>NewVal (count + 2): {{ countDouble }}</p> <button @click="inc">Increment</button> <button @click="dec">Decrement</button> <p> Message: {{ msg }} </p> <button @click="changeMessage()">Change Message</button> </div> </template> <script> export default { data() { return { count: 0, msg: 'some message' } }, computed: { countDouble() { return this.count*2 } }, watch: { count(newVal) { console.log('count changed', newVal) }, msg(newVal) { console.log('msg changed', newVal) } }, methods: { inc() { this.count += 1 }, dec() { if (this.count !== 0) { this.count -= 1 } }, changeMessage() { msg = "new Message" } } } </script>
We can see that using Composition API allows us better organization by keeping the the code (state, methods, computed properties, watchers etc) of particular features together, which was not possible in Options API.
In the above example, the code for counter
and the code for changing a message
is clearly separated in Composition API.
Using the Composition API makes sharing the code much easier. We can factor out the code for a particular feature and use it in multiple places, as shown below:
//message.js import { ref, watch } from 'vue' export function message() { let msg = ref(123) watch(msg, newVal => { console.log('msg changed', newVal) }) const changeMessage = () => { msg.value = 'new Message' } return { msg, changeMessage } }
Using the shared code in our component
<template> <div class="counter"> <p>count: {{ count }}</p> <p>NewVal (count + 2): {{ countDouble }}</p> <button @click="inc">Increment</button> <button @click="dec">Decrement</button> <p>Message: {{ msg }}</p> <button @click="changeMessage()">change message</button> </div> </template> <script> import { ref, computed, watch } from 'vue' import { message } from './common/message' export default { setup() { let count = ref(0) const countDouble = computed(() => count.value * 2) watch(count, newVal => { console.log('count changed', newVal) }) const inc = () => { count.value += 1 } const dec = () => { if (count.value !== 0) { count.value -= 1 } } let { msg, changeMessage } = message() return { count, msg, changeMessage, inc, dec, countDouble } } } </script>
In Vue 2, the template tag can only take one root element. Even if we had just two <p>
tags, we had to enclose them within a <div>
tag to get it working. Because of this, we had to change the CSS code as well in the parent component so that it looked as expected.
In Vue 3, this restriction is lifted. There is no need for a root element anymore.
We can use any number of tags directly inside the <template></template>
section:
<template> <p> Count: {{ count }} </p> <button @click="increment"> Increment </button> <button @click="decrement"> Decrement</button> </template>
Equivalent code in Vue 2:
<template> <div class="counter"> <p> Count: {{ count }} </p> <button @click="increment"> Increment </button> <button @click="decrement"> Decrement</button> </div> </template>
Suspense is a new feature that renders a default/fallback component until the main component fetches the data.
Sometimes we use async operations to fetch data from the server. Instead of handing the template with v-if and then setting it back when we return the data, Suspense does it for us.
Suspense can be used for both parts of the template, or the whole template:
<template> <Suspense> <template #default> <div v-for="item in articleList" :key="item.id"> <article> <h2>{{ item.title }}</h2> <p>{{ item.body }}</p> </article> </div> </template> <template #fallback> Articles loading... </template> </Suspense> </template> <script> import axios from 'axios' export default { async setup() { let articleList = await axios .get('https://jsonplaceholder.typicode.com/posts') .then(response => { console.log(response) return response.data }) return { articleList } } } </script>
We all know that v-model is used for two-way binding. We mostly use it with form elements. Sometimes, we even use it with custom components.
Vue-2 allowed the use of only one v-model on a component. In Vue-3, we can bind any number of v-models to our custom components:
<template> <survey-form v-model:name="name" v-model:age="age"> </survey-form> </template> //SurveyForm.vue <template> <div> <label>Name: </label> <input :value="name" @input="updateName($event.target.value)" /> <label>Age: </label> <input :value="age" @input="updateAge($event.target.value)" /> </div> </template> <script> export default { props: { name: String, age: Number }, setup(props, { emit }) { const updateName = value => { emit('update:name', value) } const updateAge = value => { emit('update:age', +value) } return { updateName, updateAge } } } </script>
Vue 2 already had great reactivity, and you might not have come across any cases where you found that reactivity was lacking. However, there were a few cases where Vue 2 fell short.
Let’s revisit Vue 2 and see what those limitations were.
To demonstrate reactivity, we’ll use watchers to listen to one of the state variables and then modify it to see if the watchers are triggered:
<template> <div class="hello" @click="test">test {{list }} {{ myObj }}</div> </template> <script> export default { name: "HelloWorld", data() { return { list: [1, 2], myObj: { name: "Preetish" } }; }, watch: { list: { handler: () => { console.log("watcher triggered"); }, deep: true } }, methods: { test() { this.list[2] = 4; this.myObj.last = "HS"; delete this.myObj.name; } } }; </script>
None of the above three modifications — such as adding a new item to an array based on the index, adding a new item to an object, or deleting an item from the object — is reactive in Vue-2. Hence watchers
won’t be triggered, or the DOM would be updated. We had to use the vue.set()
or vue.delete()
methods.
In Vue-3, these work directly without any helper functions:
export default { setup() { let list = ref([1, 2]) let a = ref(0) let myObj = ref({ name: 'Preetish' }) function myFun() { list.value[3] = 3 myObj.value.last = 'HS' delete myObj.value.name } return { myFun, list, myObj } } }
We can see that watcher
was triggered all four times in the Vue 3 setup.
When you open main.js
in the about
project, you’ll notice something different. We no longer use the Global Vue instance to install plugins and other libraries.
Instead, you can see createApp
method:
import { createApp } from 'vue' import App from './App.vue' const myApp = createApp(App) myApp.use(/* plugin name */) myApp.use(/* plugin name */) myApp.use(/* plugin name */) myApp.mount('#app')
The advantage of this feature is that it protects the Vue application from third party libraries/plugins we use which might override or make changes to the global instance — mostly by using Mixins.
Now with the createApp
method, we install those plugins on a particular instance and not the global object.
Portal is a feature where we can render a part of the code which is present in one component into a different component in a different DOM tree. There was a third-party plugin called portal-vue
that achieved this in Vue 2.
In Vue 3, portal will be built in and it is very easy to use.
Vue 3 will have a special tag called <Teleport>
, and any code enclosed within this tag will be ready to be teleported anywhere. The Teleport
tag takes a to
argument.
Let’s see this in action:
<Teleport to="#modal-layer"> <div class="modal"> hello </div> </Teleport>
Any code inside <Portal></Portal>
will be displayed in the target location mentioned.
<div id="modal-target"></div>
At the time of writing this article, <Teleport>
doesn’t work in the Alpha version mentioned above.
For more information and to develop website using Vue.js, Hire Vue.js Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft”. To develop Website using Vue.js, please visit our technology page.
Content Source:
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
© 2024 — HK Infosoft. All Rights Reserved.
© 2024 — HK Infosoft. All Rights Reserved.
T&C | Privacy Policy | Sitemap