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
With Vue 3 gaining traction and becoming the new default, many things are changing, and the ecosystem is still shaping. Until recently, the choice for state management was clearly Vuex. But with the new composition API architecture, reactivity mechanism, and some new players in the game, the choice now might be different.
Let’s explore different ways of managing the state depending on your application size and try to predict what the future of State Management in Vue.js will look like.
In options API, you can declare reactive data for a component using the data() option. Internally the object returned is wrapped with the reactive helper. This helper is also available as a public API.
If you have a piece of state that should be shared by multiple instances, you can use reactive() to create a reactive object and then import it from multiple components:
With this approach, data are centralized and can be reused across components. This can be a simple option with a minimal footprint for a small application.
A similar concept that composition API brought to the table is using a composable. This pattern, which is very popular in the React world, combined with the powerful reactivity mechanism of Vue can produce some elegant and reusable composables like the following.
Vuex is not going away. It supports Vue 3 with the same API and minimal breaking changes. The only change is that installation must happen on a Vue instance instead of the Vue prototype directly.
Vuex 4 will still be maintained. However, it’s unlikely that new functionalities will be added to it. It’s a good option if you already have a project using Vuex 3 and want to defer the migration to something else for later.
Pinia is a new store/state management system for Vue. This is a great tool for when wanting to share data between components in your application. One of the reasons for using a tool like Pinia (or Vuex for that matter) is that throwing events around and listening for these events in your application can easily become quite messy and unstructured. State management systems like Pinia (Vuex, Redux, etc.) can help solve this.
Pinia is now also the recommended choice by Vue and is now an official part of the whole Vue ecosystem, maintained and developed by core members of the Vue team. Last but not least, Pinia is super lightweight, only 1kb in size which is freaking awesome.
Pinia supports an alternative syntax to define stores. It uses a function that defines reactive properties and methods and returns them very similar to the Vue Composition API’s setup function.
In Setup Stores:
Setup stores bring a lot more flexibility than Options Stores as you can create watchers within a store and freely use any composable.
The state is a function that holds all the reactive data of this store and the getters are functions with access to the store as the first parameter. Both state and getters are identical to Vuex.
This statement doesn’t apply to actions. The context parameter has gone, and actions have access to the state and getters directly through their context(this). As you might have noticed, actions directly manipulate the state, which was strictly forbidden in Vuex.
Lastly, mutations are completely removed since state manipulation is now happening in actions.
All the magic is happening inside the setup function. The imported useFellowship hook is executed and returned. This will make it available to the component, including both methods and the template. Access to the state getters and actions are done directly using this object.
Of course, this component should be broken into smaller reusable ones but left like this for demo purposes.
If a different component needs to access the same state, it can be done in a similar manner.
Pinia docs are optimistic that code can be reused between the libraries, but the truth is that the architecture is very different, and refactoring will definitely be required. First of all, while in Vuex, we had one store with multiple modules, Pinia is built around the concept of multiple stores. The easiest way to transition that concept to be used with Pinia is that each module you used previously is now a store.
Actions no longer accept context as their first parameters. They should be updated to access state or any other context property directly. The same applies for rootState, rootGetters etc. since the concept of a single global store doesn’t exist. If you want to use another store you need to explicitly import it.
It’s evident that for large projects, migration will be complicated and time-consuming, but hopefully, a lot of boilerplate code will be eliminated, and the store will follow a more clean and modular architecture. The conversion can be done module by module rather than converting everything at once. You can actually mix Pinia and Vuex together during the migration so that this approach can work.
For more information and to develop a 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 a Website using Vue.js, please visit our technology page.
Content Source:
Vue 3 – The Progressive Javascript Framework’s progress over the years is nothing short of impressive.
If you’re someone migrating your apps to Vue 3 (or) experimenting Vue 3 for your next project this draft should help you kickstart with confidence.
If we look at the journey of Vue so far, it greatly traversed being a library to a framework trend making it much more powerful yet sticking to its lightweight nature.
With the core releasing a new major version, all the other parts of the framework needed to move forward together. Having said that, there were quite a lot of new members we would have in our party during migration. Let’s get introduced!
In short, Vue 3 would be the new default.
Vue 2 would remain in LTS (long-term support) version for 18 months, which means that it will still get security updates and is absolutely safe to stick with it for a while. But, isn’t it a great time for us to migrate our existing projects if any?
Vue 3 is faster, smaller, more maintainable and it’s easier to target native - Evan Vue
Smaller Vue core – Size improvement reached by the combination of greater code modularity, a smaller core runtime, and a tree-shaking-friendly compiler. Thus the new core would thus be reduced from about 20KB to 10KB gzipped.
The compiler will generate tree-shaking-friendly code. If you use a feature that requires a function in your template, the compiler will automatically generate code that imports it. But if you don’t use a feature, then we generate code that does not import it, which means the feature will be tree-shaken.
Better rendering performance – The Vue 3 renderer improves the performance of the rendering process by using optimizations such as the hoisting and inlining of static parts and implementing Vue 3’s reactivity with ES6 proxies.
Below is an infographic proofing the metrics between v-2.5 and v.3.0 proto
Well, despite being one of our favorite topics to speak We’ll try to wrap it short.
Vite is a lightweight and fast build toolchain with first-class Vue SFC support. It is created by Evan You, the author of Vue himself!
Vue 3 official build setup is now powered by Vite. So this would be one of our newest members to welcome!
This topic deserves a separate article on its own, yet will try to pin those dancing in my mind post my experimentations.
Vue 3 introduced the Composition API as an alternative method to the Options API for writing component states and logic. It’s simply a set of APIs that allows us to author Vue components using imported functions instead of declaring options.
It is an umbrella term that covers the following APIs:
Reactivity API, e.g. ref() and reactive(), allows us to directly create reactive state, computed state, and watchers.
Lifecycle Hooks, e.g. onMounted() and onUnmounted(), allows us to programmatically hook into the component lifecycle.
Dependency Injection, i.e. provide() and inject(), allows us to leverage Vue’s dependency injection system while using Reactivity APIs.
Vue clearly pointed out that they don’t have any plans to deprecate options API. Here’s the exact statement from the document FAQ
No, we do not have any plan to do so. Options API is an integral part of Vue and the reason many developers love it. We also realize that many of the benefits of Composition API only manifest in larger-scale projects, and Options API remains a solid choice for many low-to-medium-complexity scenarios.
We can create standalone reactive states and/or properties
In Vue 2 we’re kind of bound to the component scope for the reactive state. With Vue 3 you don’t need a component anymore to create a reactive state.
We can abstract reactive state
Sometimes setup in Vue components can get really bloated with creating many reactive properties. That’s why it could be nice to have them abstracted in standalone javascript files. This is preferably termed composable.
Better Logic Reuse
The primary advantage of Composition API is that it enables clean, efficient logic reuse in the form of Composable functions. It solves all the drawbacks of mixins, the primary logic reuse mechanism for Options API
Better Type Inference
Code written in Composition API can enjoy full type inference with little need for manual type hints.
Smaller Production Bundle and Less Overhead
Code written in Composition API and <script setup> is more efficient and minification-friendly than Options API equivalent. This is because the template in a <script setup> component is compiled as a function inlined in the same scope of the <script setup> code. Unlike property access from this, the compiled template code can directly access variables declared inside <script setup>, without an instance proxy in between. This also leads to better minification because all the variable names can be safely shortened.
Better code sharing
Inside the setup hook, we can group parts of our code by logical concern.
More Flexible Code Organization
The Options API uses options like data, methods, and mounted. With the Composition API, we have a single setup hook in which we write our reactive code.
This results in better code organization. Let’s see how with a simple code example. We’ll see how we write in Vue2, rewrite in composition API then further fine-tune with the new script setup syntax.
Having said Vue doesn’t have plans to deprecate options API anytime soon. Why should we care about composition API?
Vue 2 supports a few ways to reuse code between components;
These methods of reuse each come with their own drawbacks, namely:
Scattered logics – In Vue2, component options such as data, computed, methods, watch are used to organize the logic. This approach makes it hard to read and understand as the component grows.
<script setup> is a compile-time syntactic sugar for using Composition API inside Single File Components (SFCs). It is the recommended syntax if we are using both SFCs and Composition API. It provides a number of advantages over the normal <script> syntax:
More succinct code with less boilerplate
Ability to declare props and emitted events using pure TypeScript
Better runtime performance (the template is compiled into a render function in the same scope, without an intermediate proxy)
Better IDE type-inference performance (less work for the language server to extract types from code)
Unlike normal <script>, which only executes once when the component is first imported, code inside <script setup> will execute every time an instance of the component is created. <script setup> can be used alongside normal <script>
Pinia, a lightweight state management library for Vue.js, allows us to share a state across components/pages & gained a lot of traction recently. It uses the new reactivity system in Vue 3 to build an intuitive and fully typed state management library. It’s now the new default state management library for Vue 3. It is maintained by the Vue core team and works with both Vue 2 and Vue 3.
For more information and to develop a 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 a Website using Vue.js, please visit our technology page.
Content Source:
Performance optimization of frontend applications plays an important role in the application architecture. A higher-performing application will ensure an increase in user retention, improved user experience, and higher conversion rates.
According to Google, 53% of mobile phone users leave the site if it takes more than 3 seconds to load. At the same time, more than half of the pages tested are heavy in terms of bandwidth it utilizes to download the required assets. Don’t forget your frontend application performance directly affects its search ranking and conversion rates.
We use the Vue JS framework for our frontend applications. The challenge we had with our frontend application was with the landing page, which was taking around 3.8 secs to load with 4.2 MB of resources to be downloaded. As the response time was quite high, it was challenging to retain the users.
This article would share some of the implementation changes which we did to improve the performance of our frontend application.
Image compression is really important when optimizing frontend applications. Lighter images get downloaded faster and load with less time as compared to larger images. By compressing the images, we can make our site much lighter and hence results in slower page load times.
WebP is a modern image format that provides superior lossless and lossy compression for images on the web. Using WebP, webmasters and web developers can create smaller, richer images that make the web faster.
WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25–34% smaller than comparable JPEG images at equivalent SSIM quality index.
WebP is supported by Chrome, Firefox, Edge, and Safari from version 14 and above. Please feel free to read more about WebP.
It is evident that download time has reduced on applying webp compression.
Synchronous components loading is the process of loading the components with the import statement which is the basic way of loading the component.
Components loaded with a static import statement will be added to the existing application bundle. If code splitting is not used then the application core will become huge in size, hence affects the overall performance of the application.
The below code snippet is an example of static component loading of store and locale components.
import store from '@common/src/store' import locale from '@common/src/util/locale'
Asynchronous components loading is the process where we load chunks of our application in a lazy manner. It ensures that components are only loaded when they are needed.
Lazy loading ensures that the bundle is split and serves only the needed parts so users are not waiting to download and parse the code that will not be used.
In the below code snippet, the image of YouTube is loaded asynchronously when it’s needed.
<template> <lazy-image :lazy-src="require('@/assets/images/icon/youtube.png')" alt="YouTube" draggable="false" /> </template> <template> <img v-if="lazySrc" ref="lazy" :src="defaultImage" :data-src="lazySrc" :alt="alt" class="lazyImage" @error="handleError"> <img v-else :src="defaultImage"> </template>
To dynamically load a component, we declare a const and append an arrow function followed by the default static import statement.
We can also add a web pack magic comment. The comment will tell webpack to assign our chunk the name we provided otherwise webpack will auto-generate a name by itself.
const MainBanner = () => import(/* webpackChunkName: "c-main-banner" */ '@/components/MainBanner')
If we go to our developer tools and open the Network tab we can see that our chunk has been assigned the name we provided in the webpack’s chunk name comment.
According to Dev Mozilla, code splitting is the process of splitting the application code into various bundles or components which can then be loaded on-demand or in parallel.
As an application is used extensively, it will have a lot of changes and new requirements with time it would have increased in terms of complexity, CSS and JavaScripts files or bundles grow in size, and also don’t forget the third-party libraries which we use.
We don’t have much control in terms of third party libraries downloads as they are required for our application to work. At least we should make sure our code is split into multiple smaller files. The features required at page load can be downloaded quickly with smaller files and with additional scripts being lazy-loaded after the page or application is interactive, thus improves the performance.
we have seen some of the frontend developers’ arguments, it will increase the number of files but the code remains the same. We completely agree with them but the main thing over here is the amount of code needed during the initial load can be reduced.
Code splitting is a feature supported by bundlers like Webpack and Browserify which can create multiple bundles that can be dynamically loaded at runtime or we can do the old school way where we can split the code required for individual vue files can be separated and loaded on demand.
Basically, third-party requests can slow down page loads for several reasons like slow networks, long DNS lookups, multiple redirects, slow servers, poor performing CDN, etc.
As third-party resources (e.g., Facebook or Twitter, or MoEngage) do not originate from your domain, their behavior is sometimes difficult to predict and they may negatively affect page experience for your users.
Using preconnect helps the browser prioritize important third-party connections and speeds up your page load as third-party requests may take a long time to process. Establishing early connections to these third-party origins by using a resource hint like preconnect can help reduce the time delay usually associated with these requests.
preconnect is useful when you know the origin of the third-party request but don’t know what the actual resource itself is. It informs your browser that the page intends to connect to another origin and that you would like this process to start as soon as possible. The browser closes any connection that isn’t used within 15 seconds, so preconnect should only be used for the most critical third-party domains.
As a part of best practices, we need to make sure we don’t have any commented code in JS or CSS files. It’s commented because we don’t want to use them, so better get rid of them as the commented code contributes to an increase in the size of the file.
As part of frontend application development, we might use some CSS frameworks but you will only use a small set of the framework styles, and a lot of unused CSS styles will be included.
According to PurgeCSS, it’s a tool to remove unused CSS. It can be part of your development workflow. PurgeCSS analyzes your content and your CSS files then it matches the selectors used in your files with the ones in your content files. It removes unused selectors from your CSS, resulting in smaller CSS files.
Also while importing anything from 3rd party libraries to run the application, we can use the tree-shaking mechanism that can avoid the unused CSS and JS code included in our 3rd party bundles. To analyze this kind of unwanted JS and CSS items from 3rd party libraries there is a tool called webpack bundle analyzer.
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:
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:
Vue.nextTick allows you to do something after you have changed the data and VueJS has updated the DOM based on your data change, but before the browser has rendered those changed on the page.
// modify data vm.msg = 'Hello' // DOM not updated yet Vue.nextTick(function () { // DOM updated }
// usage as a promise (2.1.0+, see note below) Vue.nextTick() .then(function () { // DOM updated })
First GIF vs Second GIF
Can you see the difference?
The first gif uses $nextTick method
async handleFiles(fileList: FileList): Promise<void[]> { this.isFileUploaded = true; // does not work until all Promise are resolved await this.$nextTick(); // console.log(this.isFileUploaded) // true const directory = await carfsModule.setupSubDirectory(); ... }
isFileUploaded
is a state which triggers the UI change.isFileUploaded
state before Promise API call await carfsModule.setupSubDirectory()
will solve the issuethis.isFileUploaded = true; const directory = await carfsModule.setupSubDirectory(); /// ...
isFileUploaded
state is still updated AFTER / At the same time the Promise APIs are resolved [which is Second Gif ].isFileUploaded
state immediately (Before the Promise API) [which is First Gif ].this.isFileUploaded = true; // does not work until all Promise are resolved await this.$nextTick(); // console.log(this.isFileUploaded) // true const directory = await carfsModule.setupSubDirectory();
In node.js, nextTick helps its callback function to execute prior to other callback functions in Event loop.
setImmediate(() => { console.log('immediate'); }); process.nextTick(() => { console.log('nextTick'); }); setTimeout(() => { console.log('timeout'); }, 0); Promise.resolve().then(() => console.log('promise'));
has an output of :
nextTick promise timeout immediate
process.nextTick
executes prior to setImmediate
or setTimeout
.setImmediate
or setTimeout
.nextTick
has a priority over Promise.resolve
, setTimeout
, setImmediate
.
Let’s check this out example:
setTimeout(() => { console.log('timeout'); }, 0); Promise.resolve().then(() => console.log('promise')); console.log('helloworld3'); process.nextTick(() => { console.log('nextTick'); }); console.log('helloworld5');
has an output of:
helloworld3 helloworld5 nextTick promise timeout
In other words, isFileUploaded state will convert from false
to true
as a priority regardless of its place in the function.
async handleFiles(fileList: FileList): Promise<void[]> { // this.isFileUploaded = true; await this.$nextTick(); // this.isFileUploaded = true; const directory = await carfsModule.setupSubDirectory(); // this.isFileUploaded = true; }
process.nextTick
and Promise
are often called as microtask.For more Information and to build the 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 the custom website using Vue.js, please visit our technology page.
Content Source:
Before we get started, let’s first understand what we are building. The goal is to create a Vue.js component to display an image, but it should only download that image when it is in the viewport. In other words, if we have a large list of images, only the ones the user actually needs to see will be downloaded. This will speed up our apps.
Here’s the goals:
<img>
tagsWe know we will need an <img>
tag, so let’s start there. For accessibility purposes, images should always have an alt attribute, even if it’s empty. We can easily pull the alt attribute from the $attrs
or fall back to an empty string.
<template> <img :alt="$attrs.alt || ''" /> </template>
Now, something we need to fix is that we don’t actually want to set the image src attribute right away because that would cause it to download immediately.
Instead, what we want is a tiny transparent PNG that we can use as a placeholder for the image src
. Using a placeholder instead of an empty value will cause the image to take up space on the page while it waits to download the real image.
For this to work properly, we need to hijack the src attribute by expecting it as a prop
. We also need to tap into the <img>
width and height attributes to create a tiny transparent PNG with an HTML canvas, and export it as a computed property called dataUrl
.
<template> <img :src="dataUrl" :alt="$attrs.alt || ''" /> </template> <script> export default { props: { src: { type: String, required: true, }, }, computed: { dataUrl() { const { width, height } = this.$attrs if (!width || !height) return "" // create a tiny png with matching aspect ratio as img const w = 100 const canvas = document.createElement("canvas") canvas.width = w canvas.height = (height / width) * w return canvas.toDataURL() }, }, } </script>
Alright, so we’ve got a transparent image when the component lands on the page. Now we need to figure out how to set our src attribute to the real image when the component is in view.
For that, we will hook into the mounted lifecyle event and use Intersection Observer. Before we get to that, however, we need to do a little refactor.
We need a <div>
to wrap our <img>
(This will make more sense later). Divs and images behave slightly different, so we also nee a little bit of style to make sure it still behaves like a native <img>
.
<template> <div class=" app-img "> <img :src="dataUrl" :alt="$attrs.alt || ''" v-bind="$attrs" /> </div> </template> <script> export default { inheritAttrs: false, props: { src: { type: String, required: true, }, }, computed: { dataUrl() { const { width, height } = this.$attrs if (!width || !height) return "" // create a tiny png with matching aspect ratio as img const w = 100 const canvas = document.createElement("canvas") canvas.width = w canvas.height = (height / width) * w return canvas.toDataURL() }, }, } </script> <style> .app-img { display: inline-block; } </style>
Any attributes it receives should be bound to our tag and not the <div>
. We’ll use v-bind
and $attrs
for the image, and tell the component not to add the default attributes to the root <div>
by setting inheritAttrs
to false.
we’re ready to implement the Intersection Observer for lazy-loading. we won’t go into too much detail on how Intersection Observer works, but in the mounted hook, we create an IntersectionObserver
that watches for the component (via $el
) to enter the viewport. When it does, we add an event handler to the image’s ‘load’ event, and assigns the image’s src attribute (which begins loading it). We also do a bit of cleanup work to the beforeDestroy
hook just in case.
<template> <div class=" app-img "> <img :src="dataUrl" :alt="$attrs.alt || ''" v-bind="$attrs" /> </div> </template> <script> export default { inheritAttrs: false, props: { src: { type: String, required: true, }, }, computed: { dataUrl() { const { width, height } = this.$attrs if (!width || !height) return "" // create a tiny png with matching aspect ratio as img const w = 100 const canvas = document.createElement("canvas") canvas.width = w canvas.height = (height / width) * w return canvas.toDataURL() }, }, mounted() { const { src, $el } = this const observer = new IntersectionObserver(([entry]) => { const img = $el.querySelector("img") if (entry.isIntersecting) { // Element is in viewport img.src = src observer.disconnect() } }) observer.observe($el) this.$once("hook:beforeDestroy", () => { observer.disconnect() }) }, } </script> <style> .app-img { display: inline-block; } </style>
Alright, our image starts on the page as a transparent PNG, and when it enters the viewport, it loads the real image. The next thing we need to make it better some placeholder while it waits to load.
We’ll add two props for the placeholder so it can either be a background color or a different (tiny) image. We’ll also add the placeholder as a <div>
which will be absolutely positioned over the entire component.
We need to know the size of the original image so that we can stretch our placeholder to the same size. If we don’t know the width and height (we’ll cheat and use the dataUrl
computed prop), we just won’t show the placeholder:
<template> <div class=" app-img "> <div v-if="dataUrl" :style="{ background }" class=" app-img__placeholder " > <img :src="placeholder || dataUrl" alt="" v-bind="$attrs" /> </div> <img :src="dataUrl" :alt="$attrs.alt || ''" v-bind="$attrs" class=" app-img__img " /> </div> </template> <script> export default { inheritAttrs: false, props: { src: { type: String, required: true, }, placeholder: String, background: String, }, computed: { dataUrl() { const { width, height } = this.$attrs if (!width || !height) return "" // create a tiny png with matching aspect ratio as img const w = 100 const canvas = document.createElement("canvas") canvas.width = w canvas.height = (height / width) * w return canvas.toDataURL() }, }, mounted() { const { src, $el } = this const observer = new IntersectionObserver(([entry]) => { const img = $el.querySelector(`.app-img__img`) const placeholder = $el.querySelector(`.app-img__placeholder`) img.onload = function() { delete img.onload if (placeholder) { placeholder.remove() } } if (entry.isIntersecting) { // Element is in viewport img.src = src observer.disconnect() } }) observer.observe($el) this.$once("hook:beforeDestroy", () => { observer.disconnect() }) }, } </script> <style> .app-img { display: inline-block; position: relative; } .app-img__placeholder { position: absolute; } </style>
A couple of other things to note are the in the intersectionObserver
. Once the main image has loaded, we want to remove the placeholder.
Theres a few more things we can do to make it a better experience.
We’ll accomplish most of this with CSS, but we do need one class added to the image once it has finished loading. And since we have a CSS transition, we also set a timeout to remove the placeholder. Any time we set a timeout, we also want to make sure we clear it when the component is destroyed.
For more Information and to build the 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 the custom website using Vue.js, please visit our technology page.
Content Source:
Vue 3.0 – based on the reports, it looks faster, smaller, and easier to maintain than before and much more. We take a look at what’s ready for release, what needs more work, and how we’ll tackle the road ahead to Vue 3.0!
Vue 3 will be an improved evolution of the Vue.js we already know and love. It’ll take advantage of new abilities in modern browsers for better performance and use.
In general, the goal is a smooth transition over to Vue 3. No one wants a bumpy upgrade, least of all Evan You and the Vue team.
Let’s have a closer look at the main features of the 3.0 release.
Vue CLI 3.0 aims to save you from unnecessary plumbing by making sure that all its features work nicely together. More precisely, the list of what the latest release offers includes:
Vue is already fast, but the team plans to make it even faster with a few new tricks. First off, the Virtual DOM rewrite is intended to shave off time from mounting and patching, with up to 100% improvements. More compile-time hints will reduce runtime overtime.
Additionally, the rewrite should include more efficient code to create virtual nodes.
The Optimized Slots Generation is designed to ensure dependencies are tracked by the correct instance. Right now, when a parent component re-renders, its child has to as well. In Vue 3, the parent and child can be re-rendered separately.
Thanks to the new static tree hoisting, Vue 3’s compiler can skip patching entire trees. It should work with multiple occurrences. It should also reduce the cost of rendering since the compiler will be able to detect what is static and then hoist it out. For the static props hoisting, it will now be able to skip patching the node itself and patch the children.
More importantly, the new proxy-based observation is estimated to double the speed and use half the memory for Vue’s reactivity system. Designed to use the ES2015 proxies, the new system removes any previously existing caveats, which accounts for the improved performance. However, Vue 3 will still support IE11 with the old observation method.
Vue is already pretty dang small, weighing in at around 20kb gzipped. However, this new release should come in at half that, with a constant baseline size of <10kb gzipped. How? Mostly by eliminating the libraries, you’re not using, like Tree Shaking. If you don’t use the element, it’s not included.
Vue 3 will support TypeScript. Additionally, packages will be decoupled, making everything more modular and easier to maintain.
Vue 3 is also platform agnostic, so developers can utilize it with their favorite Web, iOS, or Android technologies.
While this is far from a complete list, right now we have two new experimental features:
For more Information and to build the 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 the custom website using Vue.js, please visit our technology page.
Content Source:
“Vue.js is a dynamic structure for building UIs”. Vue.js at its core is centered on the view layer just of an application, so integrating with different stages or existing applications is extremely simple. You can likewise utilize Vue.js all alone to manufacture modern single page applications.
Vue.js has got prominent reception, with many open source frameworks and enormous organizations embracing it for building up the front-end. Laravel, the leading PHP web framework, now comes with Vue.js integrated as the default front-end
Event Driven Application on the Front-End
Applications on the web today are event-driven. Vue.js gives you a chance to assemble a full-scale application that is event-driven and has all activity totally handle on the frontend. They are built to guarantee clients have a consistent experience like they would if they utilized an application introduced on their PC.
Everything happens in front-end due to which the pages are not loaded again and again for any process to take place. This event-driven concept is a feature of Vue.js.
Reactive components constitute for an event-driven app
Given that it couples pleasantly with Laravel, you will just need to make a couple of requests for information from your Laravel application and roll out UI improvements by exchanging components without reloading the page.
One can trigger UI changes that are seamless with your Vue.js frontend, which in turn gives users an incredible experience. Given Vue.js speed and execution, this happens quick and easily without taking up such a large amount of your PC resources.
Build complex frontend pages
When you make your application with Vue.js components, every component’s conditions are consequently tracked amid its render, so the framework knows decisively which part is to be updated. This makes all updates to the DOM utilize negligible assets, along these lines enhancing the general application proficiency.
Vue.js utilization of a one-way data binding model also makes state management easier in complex applications.
Single-Page Apps
Single Page Applications are the best in the most recent decade. It opens up an application to a more extensive group of users than previously.
The whole application resources get stacked once everything that your application does as the client connects with it is asking for information which commonly requires low data transmission to fulfill a request.
Easy to learn and use
Vue.js is not at all hard to get into. You feel that you are composing plain JavaScript when you utilize Vue.js and you can make a basic application with plain JavaScript and it stays legitimate in Vue.js.
Another awesome thing about Vue.js is that your substantial HTML is additionally a legitimate Vue.js layout. You can keep your CSS outside or you can process it with JavaScript relying upon your application needs. You can likewise exploit checked styling, to apply style changes to a solitary segment on the fly without the change influencing different parts.
For more Information and to build a website using Laravel, Hire Laravel 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 the custom website using Vue.js, please visit our technology page
Single Page Apps, and the frameworks that support them, provide a great opportunity to add layers of interactivity and “wow-factor” to your design. In this article we will take a look at Vue.js and how to integrate the GSAP animation library to add some to your site.
Vue.js is a Javascript framework that is both powerful and easy to pick up. With the help of Vue CLI we are able to quickly scaffold new apps with all the lastest Webpack features, without spending hours configuring your Webpack setup. Simply install Vue CLI, type vue create <project-name>
and you’re away!
GSAP is a JavaScript animation library that enables the rapid development of performant web animations. GSAP makes it easy for us to quickly string together animations to create a cohesive and flowing sequence.
When building the new ‘Daily Fire’ homepage we made heavy use of animations in an attempt to show how the product works. By using GSAP, rather than a GIF or video, we was able to add layers of interactivity to the animations to make them more engaging. Integrating GSAP with Vue.js, as you will see, is simple yet powerful.
Lets take a look at how to implement a simple Timeline with GSAP and Vue. We will be using .vue
files in this article, these are enabled by the Webpack vue-loader, automatically available with projects created with the Vue CLI.
Lets first write some markup to get an idea for what we will be animating
<template> <div ref="box" class="box"></div> </template>
<style> .box { height: 60px; width: 60px; background: red; } </style>
Here we draw a simple red box to the DOM. Take note the ref
tag on the div
, this is how we will be referring to the element when introducing GSAP. Vue makes elements with ref
tags available via this.$refs
in your component.
Now lets introduce GSAP
<template> <div ref="box" class="box"></div> </template> <script> import { TimelineLite } from 'gsap' export default { mounted() { const { box } = this.$refs const timeline = new TimelineLite() timeline.to(box, 1, { x: 200, rotation: 90 }) } } </script>
<style> /* styles emitted */ </style>
First we import TimelineLite
from GSAP, then, when the component is mounted we acquire a reference to our box
element via this.$refs
. We then initialize a GSAP timeline and play the animation.
The timeline instance exposes a to
method, with which we pass 3 arguments:
Here we can see what this small bit of code results in:
See the Pen Rotate Red Box by Samuel Parry (@smlparry) on CodePen.
Pretty simple! But lets make use of GSAP’s EasePack to give this small animation a bit more life. Using an ease is an ease’y way to make your animations feel less mechanical and more friendly. Also, you wouldn’t be making full use of GSAP’s Timeline if you didn’t queue up a few animations! Lets transition the red box to a green box, halfway through the first animation.
<template> <div ref="box" class="box"></div> </template> <script> import { TimelineLite, Back } from 'gsap' export default { mounted() { const { box } = this.$refs const timeline = new TimelineLite() timeline.to(box, 1, { x: 200, rotation: 90, ease: Back.easeInOut, // Specify an ease }) timeline.to(box, 0.5, { background: 'green' }, '-=0.5' // Run the animation 0.5s early ) } } </script>
<style> /* styles emitted */ </style>
Take note of the additional argument on line 21, here we can tell GSAP to run an animation relative to the completion of the previous. Use a +=
to specify a time after completion and -=
to specify a time before completion.
This results in:
See the Pen Rotate To Green Box by Samuel Parry (@smlparry) on CodePen.
With that simple addition we have already made our animation a lot more lively!
For more Information and to build website using Vue.js, Hire Vue.js Developer from us as we give you 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 custom 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
© 2025 — HK Infosoft. All Rights Reserved.
© 2025 — HK Infosoft. All Rights Reserved.
T&C | Privacy Policy | Sitemap