Hello everyone, I am back to my blog, this is me (although no one knows who I am).
After a period of not blogging and tingling, it was partly due to his busy work, and probably due to this Singvid Covid still has to work at home for 6 months and has not officially come back to work. the human world should be dull, the lifeless soul can’t think of anything nice to share with everyone.
Just woke up this morning to see the announcement that Vue 3 has entered the RC-stage (Release Candidate – subject to release). RC-stage is the final stage in the software development process before the official release. So the idea of an elegant hobby is writing.
As a passionate VueJS enthusiast, I also wanted to write a share with everyone (those who do not know) about Vue 3 for a long time but wanted to go to RC-stage so everything was stable and similar to the last release.
In this article we review some of the major updates that will be available in Vue through the live trial run of Vue 3.
Prerequisites
(sounds like middle school students)
First of all clone demo Vue 3 here .
After you’ve finished running npm install
or yarn install
to install node_modules
.
For those who do not know yarn: Yarn is a Facebook product, and when installing the libraries, it runs quite fast compared to npm so now I see people using yarn a lot.
After installing, we run npm run dev
or yarn dev
to run the project, open the browser at localhost:8080
see the following is a bright life, guys:
Note: currently if we open Chrome Devtool, there will be no Vue tab there, because Vue Devtool is still in the process of updating to integrate with Vue3.
Tree shaking
Open the project and see an overview as follows:
First try opening main.js
see if there is anything special:
Here we see nothing very special, simply import the App
component as the starting component (entrypoint) for our entire Vue app and mount (mount) it on the <div id="app" />
in the index.html
file
Try returning to Vue 2 to see if the main.js
file is any different:
As you can see above, the difference is that in Vue 3 instead of importing the whole Vue library, now we only import the createApp
module to serve the current purpose of creating Vue app.
This is one of the major changes in Vue 3. This technique is called tree shaking
– eliminating redundant code that is not used when building and optimizing the code . This leads to our app will be significantly smaller because there are many api like keep-alive
or slot
, … but sometimes we do not use:
Above is a comparison between Vue 2 and Vue 3 made by Evan You (creator VueJS), we can see that the build size has been reduced to half, and the time to execute JS code is also halved.
In Vue 3 almost all modules are designed to be tree-shake (v-model, nextTick, watch, …), using any module we just need to import that module (or Vue can detect and import itself). when building instead of me). As a result, our application will have a significant size reduction
Fragment
Next we open the App.vue
file to see what is available:
Oh, just opened the VSCode to report a red error, why is this ??
“The template requires 1 component-filled tag” ??? !!!
Looking back, the box is right, there are 3 cards inside, but these 3 cards are not covered by any parent card, this should normally be like this:
1 2 3 4 5 6 7 8 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> img</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> ./logo.png <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> h1</span> <span class="token punctuation">></span></span> Hello Vue 3! <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> h1</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name">@click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> inc <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Clicked {{ count }} times. <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> |
So why is the code still running without error ??
The problem is that Vue 3 no longer requires you to include all component content in a single tag, thanks to Vue 3’s default support Fragment
. Our code still runs despite seeing the red error because Vetur extension on VSCode does not support this syntax (syntax) (currently Vetur is also being updated to integrate with Vue 3).
Vue 3 Fragment is like React side with React.Fragment. Only template in Vue 3 by default supports and developers do not need to care about this.
Initially when using Vue and React I thought it was “really funny, making people have to include all the component content in one more tag, aren’t they already included in that single <template> tag”. Although later, I am familiar with and accept this, but I feel about the “developer experience” (the developer-library user experience), this problem should be supported in a “natural” way without us having to care about it. And finally Vue 3 did that
Next still in the App.vue
file look down below the logical code in the script
tag. We see the appearance of one more hook which is setup () – one of the most expected updates in Vue 3.
Composition API
In Vue 3, we see a new hook face, this hook is introduced under the Composition API name – sounds like “probably the api type synthesized by component api”
All the composition API is packed into the setup
hook, the composition API is like an optional opt-in
form, you can use it or code like Vue 2.
Using
First we modify the App.vue
file as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name">@click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> increment <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Count is: {{ state.count }}, double is: {{ state.double }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">import</span> <span class="token punctuation">{</span> reactive <span class="token punctuation">,</span> computed <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> state <span class="token operator">=</span> <span class="token function">reactive</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">,</span> double <span class="token operator">:</span> <span class="token function">computed</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> state <span class="token punctuation">.</span> count <span class="token operator">*</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">function</span> <span class="token function">increment</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> state <span class="token punctuation">.</span> count <span class="token operator">++</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> state <span class="token punctuation">,</span> increment <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Explain:
setup
is declared as normal hooks (created, mounted, etc.)- Inside we create object
state
, this object has 2 properties:count
anddouble
. We want thestate
‘s value to be reactive – when the value changes, we can see the change directly on the screen (DOM re-render), so we pass the value of thestate
object into thereactive
function imported fromvue
- In the
double
property, we want it to have twice the value of count, and almost naturally we think ofcomputed
immediately – something we are familiar with from Vue 2 when we want to have one variable with a value dependent on another. And to usecomputed
in the composition API, we simply import it from thevue
library - Along with that we have the function
increment
to increase the value ofstate.count
to 1 unit - Finally, we return the
state
andincrement
. After returning, these components will be merged with the components of the components which aredata
andmethods
as we often use in Vue 2. - Finally, on the
template
we use the components returned fromsetup
as we have done from the past
Then try reloading the browser and see the results
Important note : Everything about composition API can only be used in setup
. Ie reactive
or computed
above we use it for setup
. And by default Vue is still computed
like Vue of yesterday. For example, we modified the code 1 bit as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name">@click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> increment <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Count is: {{ state.count }}, double is: {{ state.double }}, triple is: {{ triple }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">import</span> <span class="token punctuation">{</span> reactive <span class="token punctuation">,</span> computed <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> state <span class="token operator">=</span> <span class="token function">reactive</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">,</span> double <span class="token operator">:</span> <span class="token function">computed</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> state <span class="token punctuation">.</span> count <span class="token operator">*</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">function</span> <span class="token function">increment</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> state <span class="token punctuation">.</span> count <span class="token operator">++</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> state <span class="token punctuation">,</span> increment <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> computed <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token function">triple</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> state <span class="token punctuation">.</span> count <span class="token operator">*</span> <span class="token number">3</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Try reloading the browser and let’s see:
You can see that the
setup
of thesetup
exist in a separate world, and only when returning will the return components be merged into the real world as our component withdata
,methods
,props
, ….
Oh, it looks like na na? Looks like there’s no breakthrough here, Vue 2 can do it. Continue reading this article and we will explain the great benefits of setup
offline.
Next we try to watch the value of the count and print out the console every time the count changes.
The Vue composition API provides us with watchEffect
to track the change of a variable immediately. We modified the code 1 bit as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name">@click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> increment <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Count is: {{ state.count }}, double is: {{ state.double }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">import</span> <span class="token punctuation">{</span> reactive <span class="token punctuation">,</span> computed <span class="token punctuation">,</span> watchEffect <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> state <span class="token operator">=</span> <span class="token function">reactive</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">,</span> double <span class="token operator">:</span> <span class="token function">computed</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> state <span class="token punctuation">.</span> count <span class="token operator">*</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">function</span> <span class="token function">increment</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> state <span class="token punctuation">.</span> count <span class="token operator">++</span> <span class="token punctuation">}</span> <span class="token function">watchEffect</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// chú ý vào đây</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> state <span class="token punctuation">.</span> count <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> state <span class="token punctuation">,</span> increment <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
watchEffect
code itself says what it did, right guys. It will watch whatever we define inside.
Try reloading the browser and see the results:
We can see from the very beginning that the
count
was watched and we saw a print of 0
We can also have multiple watchEffect
, each of which will watch a specific number of variables:
1 2 3 4 5 6 7 8 | <span class="token function">watchEffect</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> state <span class="token punctuation">.</span> count <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">watchEffect</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> state <span class="token punctuation">.</span> double <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Note: besides the watchEffect
composition API there is also an api called watch
, the operation is identical to the watch in the outside world that we still use in Vue 2.
1 2 3 4 5 6 7 | <span class="token function">watch</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> state <span class="token punctuation">.</span> count <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token parameter">count <span class="token punctuation">,</span> prevCount</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> count <span class="token punctuation">,</span> prevCount <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Try adding the above code and reloading the browser. (remember to import the watch
already)
Oh, oh my magic, Vue 2 already has a watch, it still looks nothing special. Keep reading to find out what’s good about it
The Composition API also provides us with a series of hooks that look like the outside world: onBeforeMount
, onMounted
, onBeforeUnmount
, onUnmounted
, …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">import</span> <span class="token punctuation">{</span> onMounted <span class="token punctuation">,</span> onUpdated <span class="token punctuation">,</span> onUnmounted <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token keyword">const</span> MyComponent <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">onMounted</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'mounted!'</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">onUpdated</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'updated!'</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">onUnmounted</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'unmounted!'</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
The more I reintroduced the composition the API looked like a normal Vue 2. onMounted
, Vue 2 is still mounted
already, onUnmounted
, onUnmounted
, we still have destroyed
in Vue 2. Is it different from the name?
What is the problem with Vue 2 currently?
In recent years, Vue has been quite popular in the frontend community, with more and more users. And there are many big projects using Vue. Now is the time when many problems arise:
- Complex, long and difficult components are difficult to read, the feature is tangible continuously, but sometimes my code has to be very difficult to find. Secondly, the architecture of a component is organized in the type of
options
, just like an object. So we haveprops
,data
,methods
,computed
, … 1 case I meet often and I believe you meet a lot of that, we have a fairly long component and we want to learn how a function works function in that component: then read thedata
see what the variable name is, drag down to read the calculation method using this variable, then drag the pull down to readcomputed
receive the results of the other method calculation, then continue pooooooooooooooowatch
to see when the othercomputed
changes, print something on the screen. So if our code is organized in alogic
, not anoption
, it’s much easier to maintain - Logging and reusing logic for components is not good and clean when the number increases, for example:
- When we import multiple mixins into a component, there will be times when we don’t know the value of a variable is coming from the mixin.
- If the mixin we import has
data
andmethod
match our existingcomponent
and obviously leads to errors. As for HOC (high order component) can lead to duplication of names inprops
- If we use HOC, then that HOC must have both the
template
and all other components as a normal Vue component, leading to redundancy while we only want to reuse each of such methods.
Let’s consider a specific example. You see this component together . The logical code is all that is included with the <script>
tag. This entire logic code is divided into several functions, each component related to the function will be colored in the same color, as the following image:
In the image above, we can see, for each function, their logic is scattered throughout the component. Encountered any long + complicated functions, but again because he had another code that he transferred to the company, he just called heaven
What does the Composition API bring us?
From the points above, the Composition API appears and rescues us:
- The properties returned from
setup
can clearly know where they came from, what file they were imported from, what type they were, etc. - These attributes can have arbitrary names so we don’t have to worry about duplicate names as mentioned above
- We also do not need to create a Vue component just for reusing the logic (as mentioned above with HOC).
- We can organize the code in a coherent logic, group the components of each function into specific clusters, or split them into a separate file.
- Composition API support is great for Typescript
Returning to the example in the previous section, with the composition API we can reorganize the code as follows :
Now the components of a function have been grouped, making it much easier to maintain code.
The Composition API will be used along with what is already available in Vue 2:
setup
will be run and return the value first of all other hooks likebeforeCreate
,created
, etc.
- Everything in the
setup
exists in a separate world, and only those returned bysetup
can be accessed from the outside world
You absolutely can not use the composition API because this is only an option if you need it. But I firmly believe that when Vue 3 officially releases people will switch to the composition API a lot for its benefits
The content of the composition API is very much and I find it quite good, solving many problems in Vue 2. Encourage you to read more about the Composition API here.
In this article, I will stop at using some basic components of Composition API
New reactive treatment mechanism
Vue 2 and some problems
In Vue 2, the core for reactive handling is through the getter
and setter
of Object.defineProperty
. The basic idea is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 | Object <span class="token punctuation">.</span> <span class="token function">defineProperty</span> <span class="token punctuation">(</span> obj <span class="token punctuation">,</span> key <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token function-variable function">get</span> <span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> value <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token function-variable function">set</span> <span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">newValue</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> value <span class="token operator">!==</span> newValue <span class="token punctuation">)</span> <span class="token punctuation">{</span> value <span class="token operator">=</span> newValue <span class="token punctuation">;</span> <span class="token function">notifyThatValueHasChanged</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
With this setup, every time we change an attribute of obj
, we will immediately notify the components related to this variable for them to update. This will happen to the data
declarations at the time the component was instantiated, and this is exactly how Vue.set
works.
Using Object.defineProperty
leads to the following:
- Update values in array:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token operator"><</span> div v <span class="token operator">-</span> <span class="token keyword">for</span> <span class="token operator">=</span> <span class="token string">""</span> name <span class="token keyword">in</span> names <span class="token operator">></span> Hello World <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token function">data</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> names <span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> names <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'John Elway'</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> names <span class="token punctuation">)</span> <span class="token comment">// đã có giá trị</span> |
In the above code, although this.names
is valid, we will not see the change on the screen, or in other words, the DOM does not re-render.
To overcome this situation, we must call this.$forceUpdate()
or use Vue.set
:
1 2 | Vue <span class="token punctuation">.</span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> names <span class="token punctuation">,</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token string">'John Elway'</span> <span class="token punctuation">)</span> |
It would be great if the mind was reeling, we forgot about this, then a week later to see the error. God help
- Add an attribute to the object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token operator"><</span> div <span class="token operator">></span> My name is <span class="token punctuation">{</span> <span class="token punctuation">{</span> user <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token constant">I</span> 'm <span class="token punctuation">{</span> <span class="token punctuation">{</span> user <span class="token punctuation">.</span> age <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token function">data</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> user <span class="token operator">:</span> <span class="token punctuation">{</span> name <span class="token operator">:</span> <span class="token string">'James'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> user <span class="token punctuation">.</span> age <span class="token operator">=</span> <span class="token number">24</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> user <span class="token punctuation">)</span> <span class="token comment">// đã có giá trị</span> |
This is probably a very common case when we add a new property and an object, and after this property changes, nothing is changed on the screen, because the other property is added outside the data
. The workaround is to call this.$forceUpdate()
or use Vue.set
1 2 | Vue <span class="token punctuation">.</span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> user <span class="token punctuation">,</span> <span class="token string">'age'</span> <span class="token punctuation">,</span> <span class="token number">24</span> <span class="token punctuation">)</span> |
And it would be great to have a quarrel with a mind-lover who is confused how to invite me to play at the weekend and still have to remember to call Vue.set
Proxy
In Vue 3, the reactive treatment mechanism has been completely replaced by Proxy .
Using Proxy for reactive processing will fix all of the above problems (whether any new problems appear or not, it is unknown).
I’ve been listening to commercials for a while now, so please show me. We reopen the App.vue
file and correct the code as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> My name is {{ user.name }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">v-if</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> user.age <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> I'm {{ user.age }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name">@click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> user.age = 24 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Set <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name">@click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> user.age++ <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Increase age <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token function">data</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> user <span class="token operator">:</span> <span class="token punctuation">{</span> name <span class="token operator">:</span> <span class="token string">'James'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Then reopen the browser and see if the result is ok:
If in Vue 2 that we do the above, then we can wear the mouse button without seeing anything changed on the screen, although if console.log
out, we see the user age
. And we have to remember to use $forceUpdate
or Vue.set
But as you can see, in Vue 3 we did not need to care about that, like adding any properties to the bed, and they will automatically react. Open up a bright future with zero $forceUpdate
and Vue.set
.
Typescript support
Over the past few years, I have noticed that people have gradually realized that pure JavaScript has many limitations, that is pure JavaScript has no mechanism to check the data type when we code, and this leads to many problems as follows:
- Data errors are only detected when the project is live
- Dev must use
console.log
e-pretend-where to check what this variable returns, what type is it, etc. Especially with non-written code. - After 1 year of reviewing the project, continue console.log everywhere again .
- When a project has many people, it gets bigger, this problem becomes even more painful and I noticed, this is really small, but it takes a lt of time in the entire software development process.
- Along with that, it leads to many inhibitions because somehow the data is not right
And Typescript appears to solve all of the above. Typescript (TS) understands plain JavaScript but has check type data when used. And I feel that using Typescript feels like having someone guide me when coding, because IDEs like VSCode are extremely powerful for TS (because TS and VSCode are Microsoft products).
If you have ever React code or React Native will see that side they have very strong and tight types system, Typescript code is very happy.
It’s started advertising again
Returning to the main theme, Vue 3 has been 100% redesigned from scratch and written in Typescript entirely. So if you guys use Typescript for your VueJS project, you will benefit greatly, now Vue code we will have the teacher to guide each of the previous code, type checking, syntax checking, etc. . Definitely will greatly reduce debug time and increase productivity.
Those who do not use Typescript will still be supported enthusiastically because VSCode is now very smart, you write pure JS still have full suggestions (of course not equal to TS)
Using Vue 2 also has support typescript but I feel the support type is “half of the season”
Currently, in my opinion, almost the entire Vue ecosystem is being updated to integrate with Vue 3 and all are written in Typescript: vue-router, vuex, vue cli, …
Such a wonderful and progressive thing, even increasing the efficiency of your work, why not try it, good brothers
Suspense
A great idea from React side that we are about to experience in Vue 3 is the Suspense
component.
Suspense
is pausing to render our main component, displaying another content instead, and until our main component is downloaded if it is an async component (lazy load) or until it’s done. Some async job is in setup
For example, I want to get the entire list of users and display on the screen, but usually we do not want to display a blank screen because the load of users list may take a long time, but we often want to display something possible. currently the data is being downloaded (for example, loading icon).
Let’s look at an example, let’s go back to the code.
We create a new component named UserList.vue
with the following content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> table</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> tr</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> th</span> <span class="token punctuation">></span></span> No. <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> th</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> th</span> <span class="token punctuation">></span></span> Name <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> th</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> tr</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> tr</span> <span class="token attr-name">v-for</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> (user, index) in users <span class="token punctuation">"</span></span> <span class="token attr-name">:key</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> index <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> td</span> <span class="token punctuation">></span></span> {{ index + 1 }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> td</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> td</span> <span class="token punctuation">></span></span> {{ `${user.name.title}. ${user.name.first} ${user.name.last}` }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> td</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> tr</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> table</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">getUsers</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span> <span class="token punctuation">(</span> <span class="token string">'https://randomuser.me/api/?results=5000'</span> <span class="token punctuation">)</span> <span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token keyword">await</span> response <span class="token punctuation">.</span> <span class="token function">json</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> data <span class="token punctuation">.</span> results <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token keyword">async</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> users <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getUsers</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> users <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Here you can see our content is quite simple: get 5000 users information, this job is done in setup()
, and finally the content is displayed by 1 table
Then we return to App.vue
and edit the content as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> List Users <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> Suspense</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token attr-name">#default</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> UserList</span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token attr-name">#fallback</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Loading... <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> Suspense</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">import</span> UserList <span class="token keyword">from</span> <span class="token string">'./UserList.vue'</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> components <span class="token operator">:</span> <span class="token punctuation">{</span> UserList <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Explain:
- Here you can see that we use a component named
Suspense
cover the content that we want to “wait”, this card is supported by default in Vue 3 liketransition
cards, we do not need to import it. - Inside, we have 2 parts marked
template
#default
and#fallback
respectively for the main component we want to display and the content displayed while waiting for the component to load.
Finally go back to the browser and see the results:
Vue 3 also provides a hook that is onErrorCaptured
to catch errors if during the processing of async tasks in setup()
occurs an error, you modify the code a bit as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | // App.vue <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">v-if</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> error <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> {{ error }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> Suspense</span> <span class="token attr-name">v-else</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token attr-name">#default</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> UserProfile</span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token attr-name">#fallback</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Loading... <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> Suspense</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">import</span> <span class="token punctuation">{</span> onErrorCaptured <span class="token punctuation">,</span> ref <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> error <span class="token operator">=</span> <span class="token function">ref</span> <span class="token punctuation">(</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token function">onErrorCaptured</span> <span class="token punctuation">(</span> <span class="token parameter">e</span> <span class="token operator">=></span> <span class="token punctuation">{</span> error <span class="token punctuation">.</span> value <span class="token operator">=</span> e <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> error <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> // UserList.vue ... async function getUsers() { let response = await fetch('https://randomuser.me/api/?results=50') let data = await response.json() throw new Error('This is error') // thêm vào duy nhất dòng này return data.results } ... |
Then try reloading the browser and you will see the following:
Above I have used
ref
,ref
here is similar toreactive
. Read more aboutref
here
In summary, I see this is a “pretty good” component, taking advantage of will help us have a better UI, catch errors / exceptions, avoid the case when running error and display a blank screen. Sometimes I use v-if
to do this, but even the condition in v-if
gets an error
Teleport
Vue 3 also supports the Teleport
component or commonly known as the Portal
(you should use React for sure. ). The goal is to render content outside of the Vue application.
When we code Vue, everything will be rendered in the <div id="app">
tag. So what if we want to render content outside of the <div id="app"
tag? ? At that time we had to write Javascript code createElement...
then document.body.appendChild...
, this is quite verbose, not intuitive, especially when the content we want to render a lot of content outward.
In Vue 3, we will have Teleport
to “move” the content we write inside Vue outside its scope.
Back to the code, modify the App.vue
file as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> Vue component <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> Teleport</span> <span class="token attr-name">to</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> #target <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Hello from Teleport <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> Teleport</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script"><span class="token language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> </span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Above, we use the Teleport
card to wrap the content we want to “move” outside, using the to
attribute to specify where we want to move our content.
Then we open the index.html
file and edit the following:
1 2 3 4 5 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> link</span> <span class="token attr-name">rel</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> stylesheet <span class="token punctuation">"</span></span> <span class="token attr-name">href</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> /dist/main.css <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">id</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> app <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">id</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> target <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token comment"><!-- Đây là nơi ta Teleport vào --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> /dist/main.js <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Finally reload the browser and we will see the following:
Open Devtool and you can see our content has been rendered outside the <div id="app">
tag as our Vue application.
One of the specific examples that I find Teleport
useful is the creation of a tooltip
:
When our component is limited in size, rendering the tooltip within the scope of the component will result in the tooltip being obscured:
Therefore we will want to display it outside the Vue application and we will be able to customize the display position most appropriately.
Global Mounting
In Vue 2, when we want to install libraries, we often use Vue.use
:
1 2 3 4 5 6 7 8 9 | <span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token keyword">import</span> Library <span class="token keyword">from</span> <span class="token string">'somelibrary'</span> Vue <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> Library <span class="token punctuation">)</span> <span class="token keyword">new</span> <span class="token class-name">Vue</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token function-variable function">render</span> <span class="token operator">:</span> <span class="token parameter">h</span> <span class="token operator">=></span> <span class="token function">h</span> <span class="token punctuation">(</span> App <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">$mount</span> <span class="token punctuation">(</span> <span class="token string">'#app'</span> <span class="token punctuation">)</span> |
But in Vue 3 we will install the following:
1 2 3 4 5 6 7 8 | <span class="token keyword">import</span> <span class="token punctuation">{</span> createApp <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">'./App.vue'</span> <span class="token keyword">const</span> myApp <span class="token operator">=</span> <span class="token function">createApp</span> <span class="token punctuation">(</span> App <span class="token punctuation">)</span> myApp <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> <span class="token comment">/* plugin name */</span> <span class="token punctuation">)</span> myApp <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> <span class="token comment">/* plugin name */</span> <span class="token punctuation">)</span> myApp <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> <span class="token comment">/* plugin name */</span> <span class="token punctuation">)</span> myApp <span class="token punctuation">.</span> <span class="token function">mount</span> <span class="token punctuation">(</span> <span class="token string">'#app'</span> <span class="token punctuation">)</span> |
Above we installed the libraries into the myApp
object, only the name “I want to install these libraries for myApp
“. Unlike in Vue 2, we install the global Vue
object. This helps protect our Vue application from third-party libraries / plugins, preventing them from changing the Vue global object – especially when using mixins
Performance
Vue 3 has been redesigned from the ground up and perhaps so Evan has many opportunities to improve the unreasonable things from version 2. These include:
- Ignore calculations during the DOM update if a node does not have any “children” (or simply 1 tag without any child tags)
- Optimize the slot slot and update the contents related to that slot
- Detect nodes that contain all the content and never change to be constant, do not perform calculations on it and re-render again.
- … Along with some other improvements you can see here
And with the improvements on Vue 3, it’s 2 times faster than current Vue 2, and 3 times faster with server side rendering. Component initialization time, compile code time are significantly reduced. Along with that is also significantly reduced the size of the build file (as I said at the beginning of the article)
Vue-router, vuex, …
Other libraries in the Vue ecosystem are also being updated to integrate with Vue 3, along with a number of improvements, you can find here.
Hot line
Evan You (creator of VueJS) posted an announcement this morning detailing the first version of the RC-stage, you read here , many great ones.
Recently Evan also developed a new tool called Vite
link here . This tool is similar to vue-cli
to create and run the VueJS project, but one feature is that it loads extremely fast whenever we update the code.
And …………….. pung piuuu
We can view the document for Vue 3, you can access it here:
(Beta is currently in progress so it should be updated a lot)
summary
Another article about Vue with an excited mood, because it has been a long time not to write anything, and eager to wait for the official day to use Vue 3 to see if there are any interesting things left.
Hopefully, through this article you can see what is waiting for us to use in the next version of Vue.
About this update, I see quite a lot of similarities with React: watchEffect
, Teleport
, Suspense
, onErrorCaptured
(similar to componentDidCatch). Evan you also share that many updates on Vue 3 are inspired by React, but I personally find them all good points, plus the cute nature of Vue, Vue 3 will be a very desirable thing. wait
I believe that with this new version, the VueJS community will increase even more because of what Vue brings: easy to learn, easy to read code and high performance.
If you have any questions, please comment below let me know. Good night everybody