In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
What are the new features of Vue3.0? in view of this question, this article introduces the corresponding analysis and answer in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.
You Da Da shared several highlights of Vue3.0 during the live broadcast of bilibili:
Performance: performance optimization
Tree-shaking support: support for tree shaking optimization
Composition API: composite API
Fragment,Teleport,Suspense: new component
Better TypeScript support: better TypeScript support
Custom Renderer API: custom renderer
In terms of performance, compared with Vue2.x, the performance is improved by about 1.3 to 2 times; the volume after packaging is also smaller, if you write a HelloWorld to package, it is only 13.5kb; with all the runtime features, it is only 22.5kb.
So how are we, as end users, different from Vue2.x when developing? Talk is cheap, let's look at the code.
Tree-shaking
One of the most important changes in Vue3 is that the smaller size of bundle brought about by the introduction of Tree-Shaking,Tree-Shaking is obvious. In version 2.x, many functions are mounted on global Vue objects, such as nextTick, set and other functions, so although we may not need them, these global functions will still be packaged into bundle as long as vue is introduced when packaging.
In Vue3, all API is introduced through ES6 modularization, which allows packaging tools such as webpack or rollup to eliminate unused API and minimize bundle volume; we can find this change in main.js:
/ / src/main.jsimport {createApp} from "vue"; import App from ". / App.vue"; import router from ". / router"; const app = createApp (App); app.use (router) .mount ("# app")
The method of creating app instances has changed from the original new Vue () to the creation of createApp functions; however, some core functions such as virtualDOM update algorithms and responsive systems will be packaged anyway; the resulting change is that components (Vue.component), instructions (Vue.directive), Vue.mixin (Vue.mixin) and plug-ins (Vue.use) that were previously configured globally are changed to methods that are directly mounted on the instance. The advantage of calling through the created instances is that an application can have multiple Vue instances, and the configuration of different instances will not affect each other:
Const app = createApp (App) app.use (/ *... * /) app.mixin (/ *... * /) app.component (/ *... * /) app.directive (/ *... * /)
Therefore, the following global API of Vue2.x also needs to be introduced into ES6 modularization:
Vue.nextTick
Vue.observable is no longer supported and changed to reactive
Vue.version
Vue.compile (full build only)
Vue.set (compatible with builds only)
Vue.delete (compatible with builds only)
In addition, both vuex and vue-router have improved using Tree-Shaking, but the syntax of api has not changed much:
/ src/store/index.jsimport {createStore} from "vuex"; export default createStore ({state: {}, mutations: {}, actions: {}, modules: {},}); / / src/router/index.jsimport {createRouter, createWebHistory} from "vue-router"; const router = createRouter ({history: createWebHistory (process.env.BASE_URL), routes,}); Lifecycle function
As we all know, there are eight lifecycle functions in Vue2.x:
BeforeCreate
Created
BeforeMount
Mounted
BeforeUpdate
Updated
BeforeDestroy
Destroyed
In vue3, a new setup lifecycle function is added. Setup is executed before the beforeCreate lifecycle function, so instances cannot be obtained through this in this function. At the same time, for the sake of unity of naming, rename beforeDestroy to beforeUnmount,destroyed to unmounted, so vue3 has the following lifecycle functions:
BeforeCreate (setup is recommended instead)
Created (setup is recommended instead)
Setup
BeforeMount
Mounted
BeforeUpdate
Updated
BeforeUnmount
Unmounted
At the same time, vue3 has added lifecycle hooks. We can access the lifecycle of components by adding on before the lifecycle function. We can use the following lifecycle hooks:
OnBeforeMount
OnMounted
OnBeforeUpdate
OnUpdated
OnBeforeUnmount
OnUnmounted
OnErrorCaptured
OnRenderTracked
OnRenderTriggered
So how do these hook functions be called? We mount the lifecycle hook in setup, and when the corresponding lifecycle is executed, the corresponding hook function is called:
Import {onBeforeMount, onMounted} from "vue"; export default {setup () {console.log ("- setup----"); onBeforeMount (() = > {/ / beforeMount code execution}); onMounted (() = > {/ / mounted code execution});},} new features
After talking about the lifecycle, here are the new features we look forward to adding to Vue3.
Responsive API
We can use reactive to create a responsive state for JS objects:
Import {reactive, toRefs} from "vue"; const user = reactive ({name: 'Vue2', age: 18,}); user.name =' Vue3'
Reactive is equivalent to Vue.observable in Vue2.x.
The reactive function only accepts complex data types such as object and array.
For some basic data types, such as strings and numeric values, we want to make it responsive, of course, we can also create objects through the reactive function, but Vue3 provides another function, ref:
Import {ref} from "vue"; const num = ref (0); const str = ref (""); const male = ref (true); num.value++;console.log (num.value); str.value = "new val"; console.log (str.value); male.value = false;console.log (male.value)
The responsive object returned by ref is a RefImpl object that contains only one parameter named value, which is obtained and modified in js through its value property; but when rendered in the template, the internal value is automatically expanded, so there is no need to append .value to the template.
{{count}} Increment count
Import {ref} from 'vue' export default {setup () {const count = ref (0) return {count}
Reactive is mainly responsible for complex data structures, while ref mainly deals with basic data structures; but many children's shoes misunderstand that ref can only handle basic data, and ref itself can handle objects and arrays:
Import {ref} from "vue"; const obj = ref ({name: "qwe", age: 1,}); setTimeout (() = > {obj.value.name = "asd";}, 1000); const list = ref ([1,2,3,4,6]); setTimeout (() = > {list.value.push (7);}, 2000)
When we are dealing with the property of some large responsive objects, we would like to use the deconstruction of ES6 to get the values we want:
Let book = reactive ({name: 'Learn Vue', year: 2020, title:' Chapter one'}) let {name,} = bookname = 'new Learn'// Learn Vueconsole.log (book.name)
Unfortunately, this will eliminate its responsiveness; in this case, we can convert the responsive object into a set of ref, and the ref will retain the responsive association with the source object:
Let book = reactive ({name: 'Learn Vue', year: 2020, title:' Chapter one'}) let {name,} = toRefs (book) / / Note that the name deconstructed here is a ref object / / you need to assign a value name.value = 'new Learn'// new Learnconsole.log (book.name) through value.
For some read-only data, we want to prevent any changes to it, and we can create a read-only object through readonly:
Import {reactive, readonly} from "vue"; let book = reactive ({name: 'Learn Vue', year: 2020, title:' Chapter one'}) const copy = readonly (book); / / Set operation on key "name" failed: target is readonly.copy.name = "new copy"
Sometimes the value we need depends on the state of other values. In vue2.x, we use the computed function to calculate properties, and in vue3 we extract the computed function, which accepts a getter function and creates an immutable responsive ref object for the value returned by getter:
Const num = ref (0); const double = computed (() = > num.value * 2); num.value++;// 2console.log (double.value); / / Warning: computed value is readonlydouble.value = 4
Alternatively, we can use the get and set functions to create a read-write ref object:
Const num = ref (0); const double = computed ({get: () = > num.value * 2, set: (val) = > (num.value = val / 2),}); num.value++;// 2console.log (double.value); double.value = 8 val / 4console.log (num.value); responsive interception
Corresponding to computed, watch,computed is a many-to-one relationship, while watch is an one-to-many relationship; vue3 also provides two functions to listen for changes in data sources: watch and watchEffect.
Let's first take a look at watch. Its usage is exactly the same as the watch option of a component. It needs to listen to a data source and then execute a specific callback function. Let's first look at how it listens to a single data source:
Import {reactive, ref, watch} from "vue"; const state = reactive ({count: 0,}); / / return worthy getter function watch (() = > state.count, (count, prevCount) = > {/ / 10 console.log (count, prevCount);}); state.count++;const count = ref (0); / / listen refwatch (count, (count, prevCount) = > {/ 20 console.log (count, prevCount, "watch");}) Count.value = 2
We can also listen for multiple values in an array, and the final value is returned as an array:
Const state = reactive ({count: 1,}); const count = ref (2); watch ([() = > state.count, count], (newVal, oldVal) = > {/ / [3,2] [1,2] / / [3,2] [3,2] console.log (newVal, oldVal);}); state.count = 3 count.value = 4
If we are listening for a deeply nested object property change, we need to set deep:true:
Const deepObj = reactive ({a: {b: {c: "hello",}); watch (() = > deepObj, (val, old) = > {/ / new hello new hello console.log (val.a.b.c, old.a.b.c);}, {deep: true}); deepObj.a.b.c = "new hello"
The final print results can be found to be changed values, because listening on a responsive object always returns a reference to that object, so we need to make a deep copy of the value:
Import _ from "lodash"; const deepObj = reactive ({a: {b: {c: "hello",}); watch (() = > _ .cloneDeep (deepObj), (val, old) = > {/ / new hello hello console.log (val.a.b.c, old.a.b.c);}, {deep: true}); deepObj.a.b.c = "new hello"
Generally speaking, listening stops automatically when the component is destroyed, but sometimes we want to stop it manually before the component is destroyed. We can call the stop function returned by watch to stop it:
Const count = ref (0); const stop = watch (count, (count, prevCount) = > {/ / do not execute console.log (count, prevCount);}); setTimeout (() = > {count.value = 2;}, 1000); / / stop watchstop ()
There is also a function watchEffect that can also be used to listen, but there is already a watch. What's the difference between this watchEffect and watch? Their usage is mainly different in the following ways:
WatchEffect does not need to manually pass in dependencies. Each initialization, watchEffect will execute a callback function to automatically get the original value. The dependent watchEffect cannot get the original value, but can only get the changed value import {reactive, ref, watch, watchEffect} from "vue"; const count = ref (0); const state = reactive ({year: 2021,}); watchEffect () = > {console.log (count.value); console.log (state.year);}); setInterval () = > {count.value++ State.year++;}, 1000)
WatchEffect automatically executes when the page is loaded, tracking response dependencies; when the timer is executed every 1 second after loading, watchEffect will listen for changes in the data and execute automatically, and the changed value will be obtained each time.
Combined API
Composition API (combined API) is also the most important feature in Vue3. The previous 2.x version adopted Options API (option API), that is, the official definition of writing: data, computed, methods, write wherever you need to write. The problem is that as the function increases, the code becomes more complex. We see that the code needs to jump up and down repeatedly:
Composition API comparison
In the figure above, a color represents a function, and we can see that the function code of Options API is relatively scattered, while Composition API can organize the logic of the same function in a function, which is convenient for maintenance.
Let's first take a look at the previous writing of Options API:
Export default {components: {}, data () {}, computed: {}, watch: {}, mounted () {},}
Options API is to put the same type of things in the same option. When we have less data, this organization is relatively clear. However, as the data increases, the function points we maintain will involve multiple data and methods, but we can't perceive which data and methods need to be involved, and we often need to switch back and forth to look up, or even need to understand the logic of other functions, which makes it difficult for components to understand and read.
What Composition API does is to maintain the code of the same function together, so that when we need to maintain a function point, we don't have to worry about other logic, but only focus on the current function; Composition API organizes the code through the setup option:
Export default {setup (props, context) {}}
We see here that it receives two parameters, props and context,props, which are some data passed in by the parent component, and context is a context object, which is some properties exposed from 2.x:
Attrs
Slots
Emit
Note: the data of props also needs to be deconstructed by toRefs, otherwise the responsive data will become invalid.
Let's take a look at the specific use of setup through a Button button:
Take a chestnut.
{{state.count} * 2 = {{double}}
{{num}}
Add
Import {reactive, computed, ref} from "vue"; export default {name: "Button", setup () {const state = reactive ({count: 1,}); const num = ref (2); function add () {state.count++; num.value + = 10;} const double = computed (() = > state.count * 2); return {state, double, num, add,} },}
A lot of children's shoes may have doubts, which is no different from what I write in data and methods, isn't it just putting them together? We can extract and split the functions in setup into a separate function, and each function can be logically reused in different components:
Export default {setup () {const {networkState} = useNetworkState (); const {user} = userDeatil (); const {list} = tableData (); return {networkState, user, list,};},}; function useNetworkState () {} function userDeatil () {} function tableData () {} Fragment
The so-called Fragment is a fragment; in vue2.x, every template must have a root node, so our code should write:
Or you can introduce the vue-fragments library in Vue2.x and replace p with a virtual fragment; in React, the solution is to create a virtual element through a React.Fragment tag; in Vue3, we don't need the root node:
Hello world
This reduces a lot of meaningless p elements.
Teleport
Teleport translates to mean transmission, long distance transmission; as the name implies, it can transfer elements or components in the slot to other locations on the page:
Portal game
In React, you can use the createPortal function to create nodes that need to be transmitted; originally, you think of Portal, but the H5 native Portal tag is also planned. Although there are some security issues, it is changed to Teleport in order to avoid duplicate names.
A common usage scenario for Teleport is to shift the location of modal boxes in some deeply nested components. Although the modal box logically belongs to this component, in terms of style and DOM structure, nesting deeper after the hierarchy is not conducive to maintenance (z-index, etc.); therefore, we need to strip it out:
Open the modal box. I'm a modal box closed.
Export default {data () {return {showDialog: false, msg: "hello"};},}
The modal p in the Teleport here is transferred to the bottom of the body; although the elements and components in the Teleport are rendered in different places, the elements and components in the Teleport are still logical child components of the parent component, and can still communicate with the parent component. Teleport receives two parameters, to and disabled:
To-string: must be a valid query selector or HTMLElement, can be id or class selector, etc.
Disabled-boolean: if true means that teleport is disabled, its slot contents will not be moved to any location, and false will not be disabled by default.
Suspense
Suspense is a built-in component introduced by Vue3, which allows our program to render some backup content while waiting for asynchronous components, allowing us to create a smooth user experience. Loading asynchronous components in Vue already exists in Vue2.x, and the routing component loaded in vue-router we use is also an asynchronous component:
Export default {name: "Home", components: {AsyncButton: () = > import (".. / components/AsyncButton"),},}
Redefined in Vue3, asynchronous components need to be defined through defineAsyncComponent for display:
/ / globally define asynchronous components / / src/main.jsimport {defineAsyncComponent} from "vue"; const AsyncButton = defineAsyncComponent (() = > import (". / components/AsyncButton.vue")); app.component ("AsyncButton", AsyncButton); / / define asynchronous components within components / / src/views/Home.vueimport {defineAsyncComponent} from "vue"; export default {components: {AsyncButton: defineAsyncComponent (() = > import (".. / components/AsyncButton"),},}
At the same time, asynchronous components can be managed more finely:
Export default {components: {AsyncButton: defineAsyncComponent ({delay: 100, timeout: 3000, loader: () = > import (".. / components/AsyncButton"), errorComponent: ErrorComponent, onError (error, retry, fail, attempts) {if (attempts)
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.