In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Most people do not understand the knowledge points of this article "what is the difference between vue3 and vue2", so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "what is the difference between vue3 and vue2" article.
1. Life cycle changes: 3.x (top) 2.x (bottom)
It is not difficult to see that the lifecycle function between vue3.0 and vue2.0 changes when it is destroyed:
BeforeDestroy-- > beforeUnmountdestroyed-- > unmounted other differences mainly lie in the language differences in writing using class components in ts. The style that can be written with reference to vue-class-component or vue-property-decorator is not much different from the option of vue2.0. If you use js to write code, you should use combination.
The problems caused by the specific changes will be explained in the combinatorial writing below.
two。 Method changes for defining global variables / / before (Vue 2.x) Vue.prototype.$http = () = > {} Vue.prototype.url= 'http://123'// after (Vue 3.x) const app = createApp ({}) app.config.globalProperties.$http = () = > {} app.config.globalProperties.url=' http://123'3. Create vue instance change / / = vue3.x// use the createApp function to instantiate vue,//, which takes a root component option object as the first parameter / / uses the second parameter We can pass the root prop to the application import {createApp} from 'vue'import App from'. / App.vue'import router from'. / router'import store from'. / store'createApp (App, {userName: "blackLieo"}) .use (store) .use (router) .mount ('# app') / / because the createApp method returns the application instance itself, other methods can be chained after it, which can be found in the following section. / / = vue2.ximport Vue from 'vue'import App from'. / App.vue'import router from'. / router'import store from'. / store' Vue ({router, store, render: h = > h (App)}). $mount ('# app') 4. Slot usage changes / / = vue2.0 uses slots basically to operate directly using slot / / in which vue2.0 has undergone two changes, and version 2.6.0 slot has been upgraded to v-slot
/ / named scope slot / / default slot
/ / the parent component calls the component
Default slot
/ / scope slot {{current.id}} {{current.name}} {{current.label}} {{current.group}} {{current.runtime}} {{current.category}} / / = vue3.0 uses slots / / in vue3.0 Slot uses v-slot for shorthand #
/ / can be written as v-slot:default # followed by slot name
Default slot
/ / scope slot / / can be written as "newData"
{{newData.aa}}
{{newData.bb}}
/ / when there are multiple slots in a component, be sure to bring the name, otherwise it may lead to scope confusion 5. Custom instruction
Implement a custom directive in Vue 2:
/ / register a global custom directive `v-focus`Vue.directive ('focus', {/ / when the bound element is inserted into the DOM. Inserted: function (el) {/ / focus element el.focus ()})
In Vue 2, custom instructions are created with the following optional hooks:
Bind: called only once, the first time an instruction is bound to an element. One-time initialization settings can be made here.
Inserted: called when the bound element is inserted into the parent node (only the parent node is guaranteed to exist, but not necessarily inserted into the document).
Update: called when the VNode of the component in which it is located is updated, but may occur before its child VNode update. The value of the instruction may or may not have changed. However, you can ignore unnecessary template updates by comparing the values before and after the update (see below for detailed hook function parameters).
ComponentUpdated: called after the VNode and its child VNode of the component to which the instruction belongs are all updated.
Unbind: called only once, when the instruction is unbound from the element.
More semantic changes have been made to the API of custom instructions in Vue 3, just like component lifecycle changes, for better semantics, as follows:
So in Vue3, you can customize instructions like this:
Const {createApp} from "vue" const app = createApp ({}) app.directive ('focus', {mounted (el) {el.focus ()}})
You can then use the new v-focus directive on any element in the template, as follows:
6.v-model upgrade
V-model has changed a lot in Vue 3:
Change: when using v-model on custom components, the default names of properties and events have changed: the .sync modifier of v-bind has been removed in Vue 3 and merged into v-model to add: the same component can set multiple v-model at the same time add: developers can customize the v-model modifier
Let's take a closer look and compare vue2 with vue3 using v-model on components
For example:
The bi-directional binding of the input box of vue2 is equivalent to passing the value property and triggering the input event:
At this point, v-model can only be bound to the value property of the component, so if we want to use a different property for our component, and we don't want to update the value by triggering input.
However, in actual development, we may need to "two-way bind" a prop in some scenarios. Here is the most common example of dialog: dialog is suitable for two-way binding of attributes, the external can control the visible display or hiding of the component, the internal closure of the component can control the hiding of visible attributes, and the visible attributes can be transferred to the external synchronously. Within the component, when we close the dialog, the event is triggered in update:PropName mode in the child component.
The event is
This.$emit ('update:visible', false)
You can then listen to this event for data updates in the parent component:
In the development of vue2, we will actually find a new thing, sync, so we can also use v-bind.sync to simplify the implementation:
I mentioned the v-model implementation in Vue2 and the two-way binding of component properties, so how should it be implemented in Vue 3?
In Vue3, using v-model on a custom component is equivalent to passing a modelValue property and triggering a update:modelValue event:
If you want to bind property names, you only need to pass a parameter to v-model, and you can bind multiple v-model at the same time:
There's nothing wrong with .sync at all. Vue 3 abandons the .sync method and uses v-model.
7. The use of asynchronous components
DefineAsyncComponent is used in Vue3 to define asynchronous components, and the configuration option component is replaced with loader. The Loader function itself no longer receives resolve and reject parameters, and must return a Promise. The usage is as follows:
Import {defineAsyncComponent} from "vue" Export default {components: {/ / Asynchronous component AsyncPage: defineAsyncComponent (() = > import (". / NextPage.vue")), / / Asynchronous component with configuration item AsyncPageWithOptions: defineAsyncComponent ({loader: () = > import (". / NextPage.vue"), delay: 200, timeout: 3000, errorComponent: () = > import (". / ErrorComponent.vue"), loadingComponent: () = > import (". / LoadingComponent.vue"),})} } 8.Composition API uses Composition API to solve the problem when we complete the function Repeated jumps in data, methods, computed, and mounted, where he maintains scattered logic together and can subdivide individual logic into separate files
If you want to know more about grammatical sugar, please go to vue3 setup grammatical sugar (partial summary)
Let's take a look at the API that Composition has.
Setup
Setup is a new option for Vue3.x, which is the entry point for using Composition API within the component.
Timing of setup execution
Through a piece of code, we can know:
Import {defineComponent, reactive} from "vue"; export default defineComponent ({beforeCreate () {console.log ("- beforeCreate----");}, created () {console.log ("- created----");}, setup () {const state = reactive ({count: 0}); console.log ("- setup----"); return {state,};},})
The output appears as follows:
The timing of setup execution is before beforeCreate, which can be explained later in the lifecycle.
Setup parameter
When using setup, it accepts two parameters:
Props: the attribute passed in by the component
Context
The props accepted in setup is responsive and will be updated in time when a new props is passed in.
Because it is responsive, you cannot use ES6 deconstruction, which eliminates its responsiveness.
Error code example, which causes props to no longer support responsiveness:
Setup (props) {const {name} = props; console.log (name); const state = reactive ({count: 0}); return {state,};}
For the above questions, we can explain in the following toRefs.
Now let's talk about:
Reactive 、 ref 、 toRefs 、 readonly
In vue2.x, the definition data is all in data.
But Vue3.x can use reactive and ref for data definition.
So what's the difference between ref and reactive?
Reactive is used to handle the two-way binding of objects, and ref handles the js base type or the two-way binding of objects. Notice that refs takes an internal value and returns a responsive and mutable ref object. The ref object has a single property.value pointing to the internal value.
Count: {{num}} s
Age of owner: {{person.age}}
Host name: {{person.name}}
Animal category: {{animal.type}}
Animal name: {{animal.name}}
Animal age: {{animal.age}}
Import {defineComponent, reactive, ref} from "vue"; export default defineComponent ({setup () {/ / declare the basic type const num = ref (0) using ref; / / declare the object const person = ref ({age: 20, name: "Zhang San"}) using ref; / / declare the object const animal = reactive ({type: "cat", name: "floret", age: 5}) SetTimeout (() = > {person.value.age = person.value.age + 1; person.value.name = "Li Si"; animal.age++;}, 1000); setInterval (() = > {num.value++;}, 1000); return {num, animal, person,};},})
It is tedious that we bind to the page through user.name,user.age;. Can we directly deconstruct the attributes in user and use them?
The answer is that you can't structure user directly, which eliminates its responsiveness, which echoes the above statement that props cannot be deconstructed directly using ES6.
What do we want to do with the deconstructed data? the solution is to use toRefs.
ToRefs is used to convert a reactive object into a normal object whose properties are all ref objects. The specific usage is as follows:
Count: {{num}} s
Age of owner: {{person.age}}
Host name: {{person.name}}
Animal category: {{atype}}
Animal name: {{aname}}
Animal age: {{aage}}
Import {defineComponent, reactive, ref, toRefs} from "vue"; export default defineComponent ({setup () {/ / declare the basic type const num = ref (0) using ref; / / declare the object const person = ref ({age: 20, name: "Zhang San"}) using ref; / / declare the object const animal = reactive ({atype: "cat", aname: "floret", aage: 5}) SetTimeout (() = > {person.value.age = person.value.age + 1; person.value.name = "Li Si"; animal.aage++;}, 1000); setInterval (() = > {num.value++;}, 1000); return {num, person,... toRefs (animal),};},})
Sometimes we want to track changes to a responsive object (ref or reactive), but we also want to prevent it from being changed somewhere in the application, when we need readonly.
For example, when we have a responsive object that is passed, we don't want it to be changed when it is passed. To do this, we can create a read-only proxy object based on the original object:
Import {reactive, readonly} from 'vue'const original = reactive ({count: 0}) const copy = readonly (original) / / modifying count via original will trigger original.count++//, a listener that depends on copy, to modify count via copy, resulting in failure and warning copy.count++ / / warning: "Set operation on key' count' failed: target is readonly."
Life cycle hook
At the beginning, we saw two pictures, in which we can sum up the changes.
We can see that beforeCreate and created have been replaced by setup (but you can still use it in Vue3 because Vue3 is backward compatible, that is, you are actually using vue2).
Second, on; Vue3.x has been added to hook naming and hook functions onRenderTriggered and onRenderTricked have been added for debugging
Let's simply use a few hooks to make it easier for you to learn how to use them. Hooks in Vue3.x need to be imported from vue:
Import {defineComponent, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered,} from "vue"; export default defineComponent ({/ / beforeCreate and created are beforeCreate () {console.log ("- beforeCreate-") of vue2;}, created () {console.log ("- created-") }, setup () {console.log ("- setup-"); / / vue3.x life cycle is written in setup onBeforeMount (() = > {console.log ("- onBeforeMount-");}); onMounted (() = > {console.log ("- onMounted-");}) OnBeforeUpdate (() = > {console.log ("- onBeforeUpdate-");}); onUpdated () = > {console.log ("- onUpdated-");}); onBeforeUnmount (() = > {console.log ("- onBeforeUnmount-");}) OnUnmounted (() = > {console.log ("- onUnmounted-");}); onErrorCaptured () = > {console.log ("- onErrorCaptured-");}); onRenderTracked (() = > {console.log ("- onRenderTracked-");}) / / debug which data has changed onRenderTriggered ((event) = > {console.log ("- onRenderTriggered-", event);});},})
Please refer to the official documentation on how to use it and what it is for. I won't repeat it here.
The usage of watch and watchEffect
The watch function is used to listen for specific data sources and to perform side effects in callback functions. The default is lazy, that is, callbacks are performed only when the listening source data changes.
Watch (source, callback, [options])
Parameter description:
Source: can support string,Object,Function,Array
Used to specify the responsive variable callback to listen for:
The callback function options executed: supports the deep, immediate, and flush options.
In fact, there are some similarities between the whole and the original vue2.0, and the basic parameters have not changed greatly.
Next, I'll show you how to use these three parameters. If you don't understand the use of watch, please read on:
/ / listen to reactive object: watch (() = > animal.aage, (curAge, preAge) = > {console.log ("New value:", curAge, "Old value:", preAge);}); / / listen to ref variable watch (num, (newVal, oldVal) = > {console.log ("New value:", newVal, "Old value:", oldVal);}) / / listening watch for multiple values ([() = > animal.aage, num], ([curAge, newVal], [preAge, oldVal]) = > {console.log ("New value:", curAge, "Old value:", preAge); console.log ("New value:", newVal, "Old value:", oldVal);}) / / when the listening object is complex, use deep listening to let the third parameter of the function be deep:truewatch (() = > state.animal, (newType, oldType) = > {console.log ("New value:", newType, "Old value:", oldType);}, {deep:true})
By default, watch is lazy, so when is it not lazy that the callback function can be executed immediately? In fact, it is also very easy to use, set it in the third parameter.
Immediate: true is fine.
/ / stop listening function const stopWatchRoom = watch (() = > state.animal, (newType, oldType) = > {console.log ("New value:", newType, "Old value:", oldType);}, {deep: true}); setTimeout () = > {/ / stop listening stopWatchRoom ();}, 3000)
There is also a listening function watchEffect, which introduces watchEffect to see the difference between its use and watch. Based on the above code, let's write it.
WatchEffect (() = > {console.log (num);})
The execution result first prints the num value; then every other second, the num value is printed.
As you can see from the above code, you don't need to pass in dependencies first like watch. WatchEffect automatically collects dependencies, as long as you specify a callback function. When the component is initialized, it is executed once to collect dependencies, and then when the data in the collected dependencies changes, the callback function is executed again. So the summary and comparison are as follows:
WatchEffect does not need to manually pass in dependencies
WatchEffect will first execute once to automatically collect dependencies
WatchEffect cannot get the value before the change, only the value after the change
9.Hooks
In the previous mixin used by vue, the so-called mixin provided a very flexible way to distribute reusable functionality in Vue components. A blended object can contain any component option. When a component uses a blending object, all options that blend into the object are "blended" into the component's own options.
Today's vue3.0 provides a new thing, vue-hooks. For specific vue-hooks, please refer to the online tutorials
Why did you produce hooks?
Let's start with class-component/vue-options:
Cross-component code is difficult to reuse
Large components, difficult to maintain, difficult to control granularity, fine-grained partition, component nesting storage level is too deep to affect performance
Class components, this is uncontrollable, logic is scattered, not easy to understand
Mixins has side effects, logic is nested, the source of data is unknown, and can not consume each other.
When a template relies on a lot of mixin, it is easy to have unclear data sources or naming conflicts, and when developing mixins, logic and logically dependent attributes are dispersed and mixin cannot consume each other. These are all very painful points in development.
Hooks has the following advantages:
Allow hooks to pass values to each other
Reuse state logic between components
Clearly point out where the logic comes from
Let's first encapsulate a hooks, if the hooks is a function that adds and subtracts age and gets double age. Store bus/useAge.ts in a separate file
Import {ref, Ref, computed} from "vue"; type CountResultProps = {age: Ref; doubleAge: Ref; increase: (curAge?: number) = > void; decrease: (curAge?: number) = > void;}; export default function useCount (initValue = 20): CountResultProps {const age = ref (initValue); const increase = (curAge?: number): void = > {if (typeof curAge! = "undefined") {age.value + = curAge;} else {age.value + = 1 }}; const doubleAge = computed (() = > age.value * 2); const decrease = (curAge?: number): void = > {if (typeof curAge! = = "undefined") {age.value-= curAge;} else {age.value-= 1;}; return {age, doubleAge, increase, decrease,};}
Call the hooks in the component
Count: {{num}} s
Age of owner: {{person.age}}
Host name: {{person.name}}
Animal category: {{atype}}
Animal name: {{aname}}
Animal age: {{aage}}
Count: {{age}}
Double age: {{doubleAge}}
Plus one minus one
Import {defineComponent, reactive, ref, toRefs, watch, watchEffect,} from "vue"; import useAge from ".. / bus/useAge.ts"; export default defineComponent ({setup () {/ / declare the base type const num = ref (0) using ref; / / declare the object const person = ref ({age: 20, name: "Zhang San"}) using ref / use reactive to declare the object const animal = reactive ({atype: "cat", aname: "floret", aage: 5}); setTimeout () = > {person.value.age = person.value.age + 1; person.value.name = "Li Si"; animal.aage++; animal.aname = "Xiao tangerine";}, 1000); setInterval () = > {num.value++;}, 1000) Const {age, doubleAge, increase, decrease} = useAge (22); return {num, person,... toRefs (animal), age, doubleAge, increase, decrease,};},}); responsive data comparison between 10.vue2.x and vue3.x
In vue2.0, a lot of people should use $set.
When the data is updated, why doesn't the page change? When do we force updates with $forceUpdate?
In vue2.x, data snooping is implemented using Object.defineProperty. And vue3.x uses Proxy.
Object.defineProperty can only hijack the properties of an object, while Proxy is a direct proxy object
Because Object.defineProperty can only hijack object properties, you need to traverse every property of the object, and if the attribute value is also an object, you need to do depth traversal recursively.
But Proxy directly proxies objects and does not need to traverse
Object.defineProperty needs to manually Observe the new attributes.
Because Object.defineProperty hijacks the properties of an object, you need to traverse the object again when adding properties
Use Object.defineProperty to hijack its new property again. That's Vue2.x.
When adding properties to arrays and objects in, you need to use $set to ensure that the new properties are also responsive
$set is also handled internally by calling Object.defineProperty.
Proxy has a variety of interception methods, such as apply,deleteProperty, and so on, which Object.defineProperty () does not have.
Proxy is that the return value is an object that can be manipulated directly, while defineProperty () has to iterate through all the object property values before it can operate.
But relatively speaking, Object.defineProperty () is more compatible.
11.Teleport
Teleport is a new feature of Vue3.x
What is Teleport?
Teleport is like an "arbitrary door" in a doa dream. The function of an arbitrary door is to instantly transfer a person to another place. With this understanding, let's take a look at why we need to use the features of Teleport. Let's look at a small example:
For example, when we use Dialog components, we often use Dialog in our actual development, and then Dialog is rendered into a layer of sub-components, which makes it difficult to deal with the positioning, z-index and style of nested components. But the component wants to be at the top of the page, at this time we mount the Dialog component on the body is the best control, we can use zIndex to control the location of the Dialog, when it is nested in the templat is not so easy. To put it simply, you want to continue to use Dialog within the component, and you want the rendered DOM structure not to be nested in the DOM within the component.
At this point, we need Teleport to play, we can wrap Dialog, and we have set up a portal that can send the content rendered by Dialog to any specified place.
Count: {{num}} s
Age of owner: {{person.age}}
Host name: {{person.name}}
Animal category: {{atype}}
Animal name: {{aname}}
Animal age: {{aage}}
Count: {{age}}
Multiple: {{doubleAge}}
Plus one minus one
Click to open Dialog this is a piece of information to cancel the confirmation
Import {defineComponent, reactive, ref, toRefs,} from "vue"; export default defineComponent ({setup () {/ / declare the basic type const num = ref (0) using ref; const dialogVisible = ref (false); / / declare the object const person = ref using ref ({age: 20, name: "Zhang San"}) / use reactive to declare the object const animal = reactive ({atype: "cat", aname: "floret", aage: 5}); setTimeout () = > {person.value.age = person.value.age + 1; person.value.name = "Li Si"; animal.aage++; animal.aname = "Xiao tangerine";}, 1000); setInterval () = > {num.value++;}, 1000) Return {dialogVisible, num, person,... toRefs (animal),};},})
We can clearly see that there is a to attribute on the teleport, which is transferred to the specified location by the current node. Where should the location be transmitted?
The answer is on index.html.
Here is our home page, and you will see that there is a p ID named dialogLL,teleport, which mounts the node here.
Vite App
As shown in the figure:
12.Suspense
Suspense is a new feature in Vue3.x, so what's its use? We understand its role through some scenarios in Vue2.x. You should often encounter scenarios like this in Vue2.x:
...
Loading.
When the front and rear end interacts to obtain data, it is an asynchronous process. Generally speaking, we will provide a loaded animation. When the data is returned, we cooperate with v-if to control the data display.
It provides two template slot, which initially renders the content in the fallback state, and does not render the formal content in the default state until a certain condition is reached, by using the
It is easier to display asynchronous rendering with Suspense components.
For specific use, we can use the following example:
This is the component that needs to wait for the value to complete:
{{getData.result}} export default {name: "NewModel", async setup () {let getData = await new Promise ((resolve) = > {setTimeout () = > {return resolve ({result: "OK"});}, 3000);}); return {getData,};},},}
Call it in other components. When the value of the component waiting for the value is completed, it will change the loading state to the OK state.
Loadding...
Import NewSuspense from ". / suspens.vue"; export default {name: "AppMain", components: {NewSuspense,},}
The effect is as shown in the figure:
13. Fragment (Fragment)
In Vue2.x, only one root node is allowed in template:
But in Vue3.x, you can write multiple root nodes directly:
14.Tree-Shaking change
Vue3.x reconstructs the global and internal API on the basis of taking into account tree-shaking. The result is that the current global API needs to be referenced by ES Module. For example, in Vue2.x, we use nextTick:
/ / vue2.ximport Vue from "vue" Vue.nextTick (() = > {...}) or this.nextTick (() = > {...})
Vue.nextTick () is a global API exposed directly from the Vue object. In fact, $nextTick () is just a simple wrapper for Vue.nextTick (), binding the this of the latter's callback function to the current instance for convenience.
Rewrite it in Vue3.x like this:
Import {nextTick} from "vue" nextTick (() = > {...})
Affected API
This is a big change because the previous global API can now only be imported by name, and this change affects the following API:
Vue.nextTick
Vue.observable (replaced with Vue.reactive)
Vue.version
Vue.compile (available in full version only)
Vue.set (available only in 2.x compatible versions)
Vue.delete (same as above)
The above is about the content of this article on "what is the difference between vue3 and vue2". I believe we all have some understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.