preface
As for VUe3, it has been more than a year since its birth. Although the usage rate is still low, the popularity and users of the community and Github are rising steadily. Therefore, learning vue3 well will be very helpful for us now and in the future. Here to write a blog, record, convenient for their future study and access
My name is Yuko, a small programmer
Introduction to Vue3
The ecology of VuE3
- Community ecology – gradually improved
- Overall optimization – Performance optimization /TS support optimization/combined API support
- Market use – VuE3 is already being used in production environments by some companies with aggressive technology selection
Community ecology
Component (plug-in) name | The official address | Introduction to the |
---|---|---|
ant-design-vue | Antdv.com/docs/vue/in… | Ant-design-vue is a VUE implementation of Ant Design, and the style of the components keeps pace with Ant Design |
element-plus | element-plus.gitee.io/#/zh-CN | Element Plus, a Vue 3.0-based desktop component library for developers, designers and product managers |
vant | Vant – contrib. Gitee. IO/vant/v3 / # / z… | The open source mobile component library of the Awesome front End team was opened in 2016 and has been maintained for 4 years |
Naive UI | www.naiveui.com/zh-CN/ | A Vue 3 component library is complete, theme tunable, uses TypeScript, not too slow, but interesting |
VueUse | vueuse.org/ | A common collection based on the Composition API |
## Vue3 development environment construction |
Next we will learn some new syntax of VUe3. First we will build a basic environment, or use the familiar VUE-CLI to quickly build an integrated vue3 environment
Task of this section: Master how to use VUE-CLI to build a development environment based on Vue3.0
1) Select custom configuration
2) Select the custom installation version
3) Select version 3.x
After the above step, vuE-CLI will help us run a vUE project with vuE3 built in
Json file, as shown in the Dependencies configuration item. The version we currently use is 3.2.0
"Dependencies ": {"vue":" 3.2.0"}Copy the code
. Then open the main entrance js file, found that some changes have taken place in the instantiation of the Vue, by previous instantiate new keywords, into createApp method call form (for more details: www.bilibili.com/read/cv1013.)
vue2.x
new Vue({
el: '#app',
render: h => h(App)
})
Copy the code
vue3.x
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
Copy the code
Finally, we opened a single file component and found that the single file component of Vue3.0 no longer requires a unique root element
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
Copy the code
That’s all we need to focus on at this stage, so we can learn vue3’s new Composition API based on our current environment
Two apis in Vue3
The Composition API is a very valuable update to vue3 for us as developers. We don’t care about the syntax, but we have a general sense of it
Objective of this section: Get a general sense of composition apis
Style contrast
Case comparison
In this section, we will take a closer look at the comparison of development modes between the two apis through a specific case study. We will ignore the syntax details for the moment and focus only on the code writing form
Objective: To understand the benefits of the Compition Api by implementing the same requirement in both Api forms
Understanding the requirements
Optional Api version implementation
<template> <div> <! <button @click="show"> </button> <button @click="hide"> </button> <div v-if="showDiv"> </div> <div> <! <button @click="changeRed"> red </button> <button @click="changeYellow"> blue </button> <div :style=" color:${fontColor} '"> </div> </div> </template> <script> export default {name: 'App', data() {return {showDiv: true, // fontColor: "// function 2 data}}, methods: Show () {this.showdiv = true}, hide() {this.showdiv = false}, ChangeRed () {this.fontColor = 'red'}, changeYellow() {this.fontColor = 'blue'}}} </script>Copy the code
Combined API version
<template> <div> <! <button @click="show"> display </button> </button @click="hide"> hide </button> <div V-if ="showDivFlag"> a div</div> </div> <div> <! <button @click="changeRed"> red </button> <button @click="changeBlue"> blue </button> <div :style=" color:${fontColor} '"> a div</div> </template> <script> import {ref} from 'vue' export default { name: 'App', Setup () {const showDivFlag = ref(true) function show() {showdivflag. value = true} function hide() { // Const fontColor = ref('') function changeRed() {fontcolor. value = 'red'} function changeBlue() { fontColor.value = 'blue' } return { showDivFlag, show, hide, fontColor, changeRed, changeBlue } } } </script>Copy the code
Combined API optimized version
You might wonder, well, now that we’re keeping all the data and behavior related to the functionality together, doesn’t the setup function get really big if you’re using a lot of functionality? It will become more difficult to maintain, so let’s take apart the huge setup function
<script> import {ref} from 'vue' // function A function useShow() {const showDivFlag = ref(true) function show() { showDivFlag.value = true } function hide() { showDivFlag.value = false } return { showDivFlag, show, Function useColor() {const fontColor = ref('') function changeRed() {fontcolor. value = 'red'} function changeBlue() { fontColor.value = 'blue' } return { fontColor, changeRed, changeBlue } } export default { name: Setup () {const {showDivFlag, show, hide} = useShow() const {fontColor, changeRed, changeBlue } = useColor() return { showDivFlag, show, hide, fontColor, changeRed, changeBlue } } } </script>Copy the code
Above, we define the function function, separate the two function related code into a separate small function, and then combine the two small function functions in the setup function, so that we can not only clean up the setup function, but also easy to maintain and quickly locate the function location
The relationship between optional and composite apis
Goal: Be able to understand the relationship between two apis
- Composite apis are intended to enhance, not replace, alternative apis, and Vue3. X supports both
- Simple scenarios are easier and more convenient to use with optional apis
- Preferred composite apis for projects that require strong TS support
- Composite apis are preferred for scenarios that require a lot of logical reuse
Nice ~ so far we have not focused on the details of the API, just to appreciate the benefits of the composite API. Now we will dive into the details of the API and see how the new API is used
Modular API
Setup entry function
Objective: To understand what the setup function does and when to call it
The main content
- The setup function is a new component option that serves as a starting point (entry) for the composite API in the component
- The setup function is executed only once when the component is initialized
- The setup function is executed before the beforeCreate lifecycle hook is executed, the instance has not been generated, and there is no this
Code demo
Export default {setup () {console.log('setup performed ') console.log(this)}, BeforeCreate () {console.log('beforeCreate performed ') console.log(this)}}Copy the code
Reactive API-Reactive
Objective of this section: Learn the functions and procedures of reactive functions
role
Reactive is a function that receives an ordinary object, converts the object data into a reactive object and returns it
Using the step
- Import from the VUE framework
reactive
function - Call reactive in the setup function and pass in the object data that you want to make responsive as arguments
- The setup function returns the value of a call to reactive as an object
Code demo
< the template > < div > {{state. The name}} < / div > < div > {{state. The age}} < / div > < button @ click = "state. The name = 'pink'" > change value < / button > </template> <script> import { reactive } from 'vue' export default { setup () { const state = reactive({ name: 'zs', age: 18 }) return { state } } } </script>Copy the code
Reactive API-ref
Objective of this section: to understand the functions and procedures of ref function
role
Ref is a function that takes an incoming simple type or complex type and returns a responsive, mutable ref object
Using the step
- Export from the VUE framework
ref
function - Called in the setup function
ref
Function and pass in data (simple or complex type) - The setup function returns the value of the ref call as an object
- Note:To use the ref result in the setup function, pass
.value
Value is not required for use in templates
Code demo
<template> <div>{{money}}</div> < button@click ="changeMondy"> </button> </template> <script> import {ref} from 'vue' export default { setup() { let money = ref(100) console.log(money.value) return { money } } } </script>Copy the code
Reactive contrast ref
Objective of this section: Know the specific nature of the two apis and how to choose between them in the project
- A ref function can take a value of a simple type and return a ref-responsive object that can be changed to compensate for the lack of simple type support in reactive functions
- Reactive and REF functions both provide reactive data conversion. There are no community best practices on which API to use and when, so you can use your own API for conversion
- Reactive is used only if we know exactly what field names are inside the object to be transformed, otherwise ref is used to reduce the mental burden of choosing a syntax
Responsive API – Computed
Objective of this section: To learn how to use computed in computing the attribute function
role
According to the existing responsive data, the new data is obtained through certain calculation
Using the step
- Import from the VUE framework
computed
function - Perform a computed function in the setup function and pass in a function that defines the calculation formula
- Put the value returned after a computed function call into an object that the setup function returns
Code demo
<template> {{ list }} {{ filterList }} <button @click="changeList">change list</button> </template> <script> import { computed, ref } from 'vue' export default { setup() { const list = ref([1, 2, 3, 4, 5, 6]) // Enter a number greater than 2 const filterList = computed(() => {return list.value.filter(item => item > 2)}) // Modify the list function changeList() { list.value.push(6, 7, 8) } return { list, filterList, changeList } } } </script>Copy the code
Responsive API-Watch
Objective of this section: to understand what the watch function does and how to use it
role
Callback logic based on changes in reactive data is the same as watch in VUe2
- Ordinary listening
- Executed immediately
- The depth of the listening
Using the step
-
Import the Watch function from the VUE framework
-
Enable listening for reactive data by executing the watch function in the setup function
-
The watch function takes three general arguments
- The first argument is a function that returns the responsive data you want to listen for changes
- The second parameter is the callback function to execute after a reactive data change
- The third parameter is an object in which to enable immediate execution or deep listening
Code demo
1) General monitoring
<template> {{ age }} <button @click="age++">change age</button> </template> <script> import { ref, watch } from 'vue' export default { setup() { const age = ref(18) watch(() => { return age.value }, () => console.log('age has changed ')}) return {age}} </script>Copy the code
2) Enable immediate execution
By default, the watch callback is executed only when the monitored data changes. If you want to execute the callback immediately, you need to configure the immediate attribute
<template> {{ age }} <button @click="age++">change age</button> </template> <script> import { ref, Watch} from 'vue' export default {setup() {const age = ref(18) watch(() => {// Return the response attribute you want to listen on. Return age.value}, () => console.log('age changed ')},{immediate: true}) return {age}} </script>Copy the code
3) Enable deep listening
By default, when the data we are listening to is an object, the callback function will not be executed if the properties inside the object are changed. If you want all properties of the object to be listened on, you need to enable the deep configuration
<template> {{ state.name }} {{ state.info.age }} <button @click="name = 'pink'">change name</button> <button @click="info.age++">change age</button> </template> <script> import { reactive, toRefs, watch } from 'vue' export default { setup() { const state = reactive({ name: 'zs', info: { age: 18}}) watch(() => {return state}, () => {console.log('age changed ')}, {deep: true }) return { state } } } </script>Copy the code
4) A better way
When using Watch, be as specific as possible about which properties you want to listen for to avoid the performance problems associated with using deep. For example, I only want to perform a callback when the age property of the state object changes
<template> {{ state.name }} {{ state.info.age }} <button @click="state.name = 'pink'">change name</button> <button @click="state.info.age++">change age</button> </template> <script> import { reactive, toRefs, watch } from 'vue' export default { setup() { const state = reactive({ name: 'zs', info: { age: 18}}) watch(() => {return state.info.age}, () => console.log('age changed ')}) return {state}}} </script>Copy the code
Life cycle function
Review the life cycle
Objective of this section: review the lifecycle and understand the role of the lifecycle
Use the lifecycle hook function in the setup function
Goal of this section: Learn how to use life cycle functions in setup functions
Using the step
- Import from vUE first
On heading
The lifecycle hook function of - Call the lifecycle function in the setup function and pass in the callback function
- Lifecycle hook functions can be called multiple times
Code demo
<template> <div> Life cycle function </div> </template> <script> import {onMounted} from 'vue' export default {setup() {// The time is ripe OnMounted (() => {console.log('mouted lifecycle ')}) onMounted(() => {console.log('mouted lifecycle ')})}} </script>Copy the code
Life cycle functions under the optional API | Use of life cycle functions under the composite API |
---|---|
beforeCreate |
No need (directly to the setup function) |
created |
No need (directly to the setup function) |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeDestroy Vue 3: beforeUnmount |
onBeforeUnmount |
destroyed Vue 3: unmounted |
onUnmounted |
Lifecycle hook function usage scenarios
Lifecycle hook functions | Application scenarios |
---|---|
created | Send ajax requests/mount shared properties |
mounted | Send Ajax requests/DOM-dependent businesses such as maps, charts |
destroyed -> unmounted | Destroy operations, such as timers |
Parent-child communication
Objective of this section: Master parent-child communication under the combined API
In vue3 combined API, the basic routine of parent to child is exactly the same, the basic idea is still: parent to child is passed in through prop, and child to parent is completed by calling custom events
Implementation steps
- The setup function takes two arguments, the first parameter being props and the second parameter being an object context
- Props is an object that contains all prop data passed by the parent component. The context object contains the attrs, slots, emit properties, of which the props is an object
emit
You can trigger the execution of a custom event to complete child to parent transmission
Code demo
app.vue
<template>
<son :msg="msg" @get-msg="getMsg"></son>
</template>
<script>
import { ref } from 'vue'
import Son from './components/son'
export default {
components: {
Son
},
setup() {
const msg = ref('this is msg')
function getMsg(msg) {
console.log(msg)
}
return {
msg,
getMsg
}
}
}
</script>
Copy the code
components/Son.vue
<template> <div> {{msg}} <button @click="setMsgFromSon">set</button> </div> </template> <script> export default { props: { msg: { type: String } }, emits: ['get-msg'], Setup (props,{emit}) {function setMsgFromSon(){emit('get-msg',' this is a new MSG message from a child component ')} return {// Declare a custom event triggered by the current component setup(props,{emit}) {function setMsgFromSon(){emit('get-msg',' this is a new MSG message from a child component ')} return { setMsgToSon } } } </script>Copy the code
Dojo.provide and inject
1. Application scenarios
Objective of this section: to be able to clarify the usage scenarios of this API, and what problems are solved
Usually, we use props to transfer data between parent and child. However, if components are nested at a deeper level, layer by layer transmission becomes very complicated. Is there a way to simplify this process? Together, they make it easy to transfer data from a top-level component to any underlying component
2. Basic use
Objective of this section: To learn the basics of using provide and Inject in setup functions
Requirement: the parent component has a copy of data passed to the grandson component for direct use
Implementation steps
-
The top-level component provides data in the setup method using the provide function
Provide ('key', data)
-
Any underlying component retrieves data using the Inject function in the setup method
const data = inject('key')
The code to the ground
Grandpa component - app.vue
<template> <father></father> </template> <script> import Father from '@/components/Father' import { provide } from 'vue' export default { components: {Father}, setup() {let name = 'Father' // provide key-value provide('name', name)}} </script>Copy the code
Suncomponent-components/son.vue
<template> I am a child component {{name}} </template> <script> import {inject} from 'vue' export default {setup() {const name = inject('name') return { name } } } </script>Copy the code
In fact, any descendant component can easily access the data provided by the top-level component
Pass reactive data
By default, the data transferred by provide is not reactive, that is, if the data provided by provide is modified, it cannot affect the use of data by underlying components in a reactive manner. If you want to transfer the response data, you only need to use REF or Reactive to generate the passed data
Objective of this section: How to provide/inject responsive data
app.vue
<template> <father></father> <button @click="changeName">change name</button> </template> <script> import Father from '@/components/Father' import { provide, ref } from 'vue' export default { components: { Father }, Function changeName(){name.value = 'pink'} provide('name', name) return { changeName } } } </script>Copy the code
TemplateRef
The goal of this section is to learn how to get a DOM node or component instance object using ref in the Setup function
Background knowledge
When we use ref in templates, we all know that there are three common scenarios for using it
- Ref + Plain DOM tag gets the real DOM object
this.$refs.box
- This.$refs.form.validate()
- Ref + V-for gets an array of DOM objects (instance objects) (not often used)
Implementation steps
- Create a ref object with null =>
const hRef = ref(null)
- Create a template association by defining the name of the ref object created in the ref attribute =>
<h1 ref="hRef"></h1>
- the
hRef
Return to go out - Using = >
hRef.value
The code to the ground
components/RefComponent.vue
<template> I am a normal component </template>Copy the code
app.vue
<template> <h1 ref="h1Ref"> I am a normal DOM tag </h1> <ref-component ref="comRef"></ref-component> </template> <script> import { onMounted, ref } from 'vue' import RefComponent from '@/components/RefComponent' export default { components: { RefComponent }, setup() { const h1Ref = ref(null) const comRef = ref(null) onMounted(() => { console.log(h1Ref.value) Console. log(comref.value)}) // Must return return {h1Ref, comRef}} </script>Copy the code
Incompatible syntax
Vue3.0 is compatible with most of the syntax of version 2.0, but there are some damaging syntax updates, which should be paid attention to
-
Instance method $ON removed (Existing implementation mode of eventBus no longer supports tripartite plug-in instead)
event Bus 1. Vue.prototype.$eventBus = new Vue() 2. Receiving data of the components in this. $eventBus. $on (' get - MSG '(MSG) = > {}) 3. $emit('get-msg',' sent data ') in vue3, eventBus mode is not supported by default using third-party plugins insteadCopy the code
-
Filter removed (interpolation can no longer use filters, can use methods instead)
The filter filter string formatting method receives the original string Returns the formatted string {{MSG | formatMsg}} vue3 directly removed the grammar can directly use the methods to replace {{formatMsg (' this is the MSG ') }} // What is the result of rendering? {formatMsg(MSG){return MSG + 'zs'}}Copy the code
-
.sync syntax removed (merged with V-model syntax)
ElementUI -> Dialog visible. Sync ="showFlag"Copy the code
Read more: v3.cn.vuejs.org/guide/migra…