Vue 3.0 It was finally released on September 18, 2020 and has been used Typescript A large-scale reconstruction has been carried out, which has brought Composition API RFC Version, similar React Hook Write Vue in the same way. You can customize your own hook to make users more flexible.
Some new features of vue 3.0.
- setup()
- ref()
- reactive()
- isRef()
- toRefs()
- computed()
- watch()
- Lifecycle hooks
- Template refs
- globalProperties
- Suspense
Comparison of Vue2 and Vue3
-
Unfriendly to TypeScript support (all attributes are placed on this object, which is difficult to push down the data type of the component)
-
A large number of API s are mounted on the prototype of Vue objects, which is difficult to implement TreeShaking.
-
The architecture layer is not friendly to cross platform dom rendering development support
-
Composition API . Inspired by ReactHook
-
More convenient support jsx
-
Vue 3's Template supports multiple root tags, but Vue 2 does not
-
Rewrite the virtual DOM and optimize the compilation of the template
I setup function
The setup() function is a new attribute provided specifically for components in vue3. It provides a unified entry for us to use the new features of vue3's Composition API. The setup function will be executed before beforeCreate and created. Vue3 also cancels these two hooks and replaces them with setup. This function is equivalent to a life cycle function. All the past data, methods and watch in Vue are written in the setup() function with the corresponding new api
setup(props, context) { context.attrs context.slots context.emit return { } }
- Props: used to receive props data
- Context is used to define the context. The context object contains some useful attributes. These attributes can only be accessed through this in vue 2.x. This cannot be accessed in the setup() function. It is undefined
- Return value: return {}, which returns responsive data and functions to be used in the template
II reactive function
The reactive() function receives a common object, return s a response data object, and wants to use the created response data. It is also very simple. After it is created, it goes out in setup, and it can be called directly in template.
<template> {{name}} // test <template> <script lang="ts"> import { defineComponent, reactive, ref, toRefs } from 'vue'; export default defineComponent({ setup(props, context) { let state = reactive({ name: 'test' }); return state } }); </script>
III ref function
The ref() function is used to create a responsive data object according to the given value. The return value of the ref() function call is an object. This object only contains a value attribute. If you access the ref function inside the setup function, you need to add. Value
<template> <div class="mine"> {{count}} // 10 </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; export default defineComponent({ setup() { const count = ref<number>(10) // To get the value defined in ref in js, you need to use the value attribute console.log(count.value); return { count } } }); </script>
Access the responsive data created by ref in the reactive object
<template> <div class="mine"> {{count}} -{{t}} // 10 -100 </div> </template> <script lang="ts"> import { defineComponent, reactive, ref, toRefs } from 'vue'; export default defineComponent({ setup() { const count = ref<number>(10) const obj = reactive({ t: 100, count }) // The. Value attribute is not required to obtain the value of ref through reactive console.log(obj.count); return { ...toRefs(obj) } } }); </script>
IV isRef function
isRef() is used to determine whether a value is an object created by ref()
<script lang="ts"> import { defineComponent, isRef, ref } from 'vue'; export default defineComponent({ setup(props, context) { const name: string = 'vue' const age = ref<number>(18) console.log(isRef(age)); // true console.log(isRef(name)); // false return { age, name } } }); </script>
V toRefs function
The toRefs() function can convert the responsive object created by reactive() into an ordinary object. However, each attribute node on this object is responsive data of ref() type
<template> <div class="mine"> {{name}} // test {{age}} // 18 </div> </template> <script lang="ts"> import { defineComponent, reactive, ref, toRefs } from 'vue'; export default defineComponent({ setup(props, context) { let state = reactive({ name: 'test' }); const age = ref(18) return { ...toRefs(state), age } } }); </script>
Vi computed Create calculated properties
The computed function is used to create calculated attributes. As in the past, the value it returns is a ref object. You can pass a method or an object, which contains set() and get() methods
6.1 create read-only calculated attributes
import { computed, defineComponent, ref } from 'vue'; export default defineComponent({ setup(props, context) { const age = ref(18) // Create a responsive calculation attribute readOnlyAge according to the value of age, // It automatically calculates and returns a new ref based on the dependent Ref const readOnlyAge = computed(() => age.value++) // 19 return { age, readOnlyAge } } }); </script>
6.2 create a readable and writable calculation attribute through set() and get() methods
<script lang="ts"> import { computed, defineComponent, ref } from 'vue'; export default defineComponent({ setup(props, context) { const age = ref<number>(18) const computedAge = computed({ get: () => age.value + 1, set: value => age.value + value }) // The operation of assigning value to the calculated attribute will trigger the set function, // After triggering the set function, the value of age will be updated age.value = 100 return { age, computedAge } } }); </script>
VII watch Monitor data
The watch function is used to listen to a specific data source and perform side effects in the callback function. The default is lazy execution, that is, the callback is executed only when the listening source data changes.
7.1 listening to data sources declared with reactive
<script lang="ts"> import { computed, defineComponent, reactive, toRefs, watch } from 'vue'; interface Person { name: string, age: number } export default defineComponent({ setup(props, context) { const state = reactive<Person>({ name: 'vue', age: 10 }) watch( () => state.age, (age, preAge) => { console.log(age); // 100 console.log(preAge); // 10 } ) // When modifying the age, the callback of watch will be triggered to print the values before and after the change state.age = 100 return { ...toRefs(state) } } }); </script>
7.2 listening to data sources declared with ref
<script lang="ts"> import { defineComponent, ref, watch } from 'vue'; interface Person { name: string, age: number } export default defineComponent({ setup(props, context) { const age = ref<number>(10); watch(age, () => console.log(age.value)); // 100 // When modifying the age, the callback of watch will be triggered to print the changed value age.value = 100 return { age } } }); </script>
7.3 simultaneous monitoring of multiple values
<script lang="ts"> import { computed, defineComponent, reactive, toRefs, watch } from 'vue'; interface Person { name: string, age: number } export default defineComponent({ setup(props, context) { const state = reactive<Person>({ name: 'vue', age: 10 }) watch( [() => state.age, () => state.name], ([newName, newAge], [oldName, oldAge]) => { console.log(newName); console.log(newAge); console.log(oldName); console.log(oldAge); } ) // When modifying the age, the callback of watch will be triggered to print the values before and after the change, // At this time, it should be noted that changing one of the values will execute the callback of watch state.age = 100 state.name = 'vue3' return { ...toRefs(state) } } }); </script>
7.4 execute the return method to stop listening
The watch monitoring created in the setup() function will automatically stop when the current component is destroyed. If you want to explicitly stop a monitoring, you can call the return value of the watch() function. The syntax is as follows:
<script lang="ts"> import { set } from 'lodash'; import { computed, defineComponent, reactive, toRefs, watch } from 'vue'; interface Person { name: string, age: number } export default defineComponent({ setup(props, context) { const state = reactive<Person>({ name: 'vue', age: 10 }) const stop = watch( [() => state.age, () => state.name], ([newName, newAge], [oldName, oldAge]) => { console.log(newName); console.log(newAge); console.log(oldName); console.log(oldAge); } ) // When modifying the age, the callback of watch will be triggered to print the values before and after the change, // At this time, it should be noted that changing one of the values will execute the callback of watch state.age = 100 state.name = 'vue3' setTimeout(()=> { stop() // At this time, the watch callback will not be triggered during modification state.age = 1000 state.name = 'vue3-' }, 1000) // Cancel the monitoring of watch in 1 second return { ...toRefs(state) } } }); </script>
VIII LifeCycle Hooks (New lifecycle function)
The new version of life cycle functions can be imported into components on demand and can only be used in the setup() function, but they can also be defined outside setup and used in setup
<script lang="ts"> import { set } from 'lodash'; import { defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onErrorCaptured, onMounted, onUnmounted, onUpdated } from 'vue'; export default defineComponent({ setup(props, context) { onBeforeMount(()=> { console.log('beformounted!') }) onMounted(() => { console.log('mounted!') }) onBeforeUpdate(()=> { console.log('beforupdated!') }) onUpdated(() => { console.log('updated!') }) onBeforeUnmount(()=> { console.log('beforunmounted!') }) onUnmounted(() => { console.log('unmounted!') }) onErrorCaptured(()=> { console.log('errorCaptured!') }) return {} } }); </script>
IX Template refs
Get the real dom elements through refs. This is the same as the use of react. In order to obtain references to elements or component instances in the template, we can declare a ref in setup() and return it as usual
- As usual, write the name of ref in html
- Define a ref in setup
- Instance of ref returned in setup
- The RefImpl object of ref can be obtained in onMounted, and the real dom can be obtained through. value
<template> <!--Step 1: as usual, in html Write in ref Name of--> <div class="mine" ref="elmRefs"> <span>span</span> </div> </template> <script lang="ts"> import { set } from 'lodash'; import { defineComponent, onMounted, ref } from 'vue'; export default defineComponent({ setup(props, context) { // Get real dom const elmRefs = ref<null | HTMLElement>(null); onMounted (() => { console.log(elmRefs.value); // Get a RefImpl object and access the data through. value }) return { elmRefs } } }); </script>
X Global configuration of vue
It is configured through config on Vue instance, including the objects of Vue application global configuration. You can modify the properties listed below before mounting the application:
const app = Vue.createApp({}) app.config = {...}
Assign handlers for uncapped errors during component rendering and watchers. Errors and application instances call handlers
app.config.errorHandler = (err, vm, info) => {}
Global properties that can be accessed in any component instance within the application, and the properties of the component will have priority. This can replace the Vue 2.x Vue.prototype extension:
const app = Vue.createApp({}) app.config.globalProperties.$http = 'xxxxxxxxs'
You can use getCurrentInstance() to obtain the information configured in global properties in the component. getCurrentInstance method obtains the instance of the current component, and then obtains the current context through ctx property. In this way, we can use router and vuex in setup. Through this property, we can operate variables, global properties, component properties, etc
setup( ) { const { ctx } = getCurrentInstance(); ctx.$http }
Xi Suspend component
Before introducing Vue's suspend component, it is necessary to understand the suspend component of React because their functions are similar.
React.lazy accepts a function that needs to dynamically call import(). It must return a Promise that needs to resolve a react component of default export.
import React, { Suspense } from 'react'; const myComponent = React.lazy(() => import('./Component')); function MyComponent() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <myComponent /> </Suspense> </div> ); }
Vue3 also adds the defineAsyncComponent function with similar function of React.lazy to handle dynamic introduction. defineAsyncComponent can accept factory functions that return commitments. When you retrieve the component definition from the server, you should call Promise's parsing callback. You can also call reject(reason) to indicate that the load has failed
import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => import('./components/AsyncComponent.vue') ) app.component('async-component', AsyncComp)
Vue3 also added the suspend component:
<template> <Suspense> <template #default> <my-component /> </template> <template #fallback> Loading ... </template> </Suspense> </template> <script lang='ts'> import { defineComponent, defineAsyncComponent } from "vue"; const MyComponent = defineAsyncComponent( () => import('./Component') ); export default defineComponent({ components: { MyComponent }, setup() { return {} } }) </script>
12, vue 3.x complete component template structure
A completed vue 3.x complete component template structure includes: component name, props, components, setup (hooks, computed, watch, methods, etc.)
<template> <div class="mine" ref="elmRefs"> <span>{{name}}</span> <br> <span>{{count}}</span> <div> <button @click="handleClick">Test button</button> </div> <ul> <li v-for="item in list" :key="item.id" >{{item.name}}</li> </ul> </div> </template> <script lang="ts"> import { computed, defineComponent, getCurrentInstance, onMounted, PropType, reactive, ref, toRefs } from 'vue'; interface IState { count: 0, name: string, list: Array<object> } export default defineComponent({ name: 'demo', // Parent component to child component parameters props: { name: { type: String as PropType<null | ''>, default: 'vue3.x' }, list: { type: Array as PropType<object[]>, default: () => [] } }, components: { ///TODO component registration }, emits: ["emits-name"], // For cue setup (props, context) { console.log(props.name) console.log(props.list) const state = reactive<IState>({ name: 'vue 3.0 assembly', count: 0, list: [ { name: 'vue', id: 1 }, { name: 'vuex', id: 2 } ] }) const a = computed(() => state.name) onMounted(() => { }) function handleClick () { state.count ++ // Call the method of the parent component context.emit('emits-name', state.count) } return { ...toRefs(state), handleClick } } }); </script>
Ecology of vue 3
Official website [1]
Source code [2]
vite builder [3]
Scaffold: [4]https://cli.vuejs.org/
vue-router-next[5]
vuex4.0[6]
UI component library
vant2.x[7]
Ant Design of Vue 2.x[8]
element-plus[9]
From [original address]( https://mp.weixin.qq.com/s?__biz=MzAxODE4MTEzMA==&mid=2650081599&idx=1&sn=d28ae78f205640f7f812318b8b5ccc71&chksm=83db945ab4ac1d4c627a6c44c4d2af3112280de79ae22ecbfe583784b7a73f9a9af220acede4&mpshare=1&scene=23&srcid=1028IwSO0yCUEmj06ewGjQWb&sharer_sharetim )