preface
What changes did the transition from vue2. X to vue3. This article starts with creating a VUE3 project. Let’s take a look at what changes vuE3 has made and what benefits it can bring us
First, why learn Vue3
1. The status quo
- Released in 2020.09.18, the surrounding ecology is not supported, most developers are in wait-and-see.
- Mainstream component library
element-plus
、vant
,ant-design-vue
Vue3.0 has been released, this is the trend.
2. Vue3 advantages
- One of the hottest front end frames in the country
- Performance improvement
- A smaller
- Type inference: better support for TS(supersets of JS)
- Advanced giving exposes lower-level apis and provides more advanced built-in components
Do things
Option API—–> Composition API, can better organize logic, packaging logic, reuse logic (programming style change)
3. Vue3 outlook
- trend
- Large projects, due to Ts friendly, more and more large projects can use VUe3.0
How to create vuE3 application
1. Create projects based on Vue scaffolding
Install vUE scaffolding globally
npm i @vue/cli -g
# create Vue project, select V3 versionVue create Project name#-------- after creation --------
# Change path
cdThe project name# Run the project
npm run serve
Copy the code
Operation steps:
-
Locate the root directory where you want to create the project and enter CMD in the address bar to open the terminal
-
Enter vue create project name
-
Select manual creation (figure)
- Select the required configuration (select space and press Enter after selecting)
- You can select each configuration according to the following figure
2. Analysis of import files
Vue3’s API is typically imported on demand
The chain operation
What it does: Render the App root component into the index.html page
Conclusion:
- Vue is instantiated based on createApp method
- The use method is used to configure the router and store
- Import on demand to improve packaging performance
3. App.vue root component structure analysis
The component template in Vue2 must have a unique root node
A template for a component in Vue3 can have no root node
Summary: Component templates in Vue3 can have no root node (contrast with Vue2)
4. Analyze the router file
Vue3 creates instance objects
Conclusion:
- Create a route instance object using the createRouter mode, typical Vue3 style
- There are changes in the way hash and history are used
- The mode option for Vue2 is hash/history
- Vue3 createWebHashHistory()/createWebHistory()
5. Vuex file analysis
Conclusion: Create a Store object using the createStore method instead of new
Option API and composition API
Goal: Understand what option API writing is and what composition API is
1. The options for API
Where each code is written
2. The combination of the API
Division by function
Conclusion:
- Option API used in the Vue2 project
- Code style: a functional logic code dispersion
- Advantages: Easy to learn and use, the location of the code has been agreed
- Disadvantages: poor code organization, similar logic (function) code is not easy to reuse, logic complex
- Combination of API (hook)
- Block code structure by function, making it easier to reuse functionality later
4. Combination of API related methods
1. The setup function
Usage details:
-
New component options as a starting point for using composite apis in components
-
In terms of the component lifecycle, it is executed before beforeCreate (Vue3 beforeCreate/created is deprecated and has been replaced by setup).
-
This is not yet created in the setup function, so you cannot access this; this is undefined
-
The data returned in setup is used for template use: similar to the data provided in the previous data
-
Data from Data can still be used in Vue3, but not recommended (this is how the option API is written)
-
Methods defined in Setup also need to return
Syntax format:
export default {
setup() {
// return ... }}Copy the code
Conclusion:
- The Setup option is the basis for implementing the composite API
- Trigger time:
- This problem
- The return value of setup
2. Life cycle
Vue2. X lifecycle hook functions:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestory
- destroyed
Recognize vue3.0 lifecycle hook functions (the same lifecycle function can fire multiple times)
setup
Before creating an instanceonMounted
Mount after the DOMonBeforeUpdate
Before updating componentsonUpdated
After updating componentsonBeforeUnmount
Before unloading and destructiononUnmounted
: After uninstallation and destruction
Syntax format:
import { mounted } from 'vue'
export default {
setup () {
mounted(() = > {
console.log('xxx')}}}Copy the code
Conclusion:
- The VUe3 lifecycle function has changed
- Remove two:
beforeCreate
andcreated
To add setup- Method names changed: The method name was preceded by an ON with a hump in the middle
- Uninstall component lifecycle changes:
onBeforeUnmount
,onUnmounted
- Features: The same life cycle can trigger multiple times
5. Data responsiveness
Data responsiveness: Changes in data cause views to change automatically.
1. The reactive function
A complex data type can be defined
Syntax format:
Use obj.msg in the template
import { reactive } from 'vue'
export default{
setup(){
const obj = reactive({
msg: 'Hello'}}})Copy the code
Note: Object properties in Reactive lose their responsiveness if they are reassigned
2. ToRef function
Requirement: The template does not add obj prefix, directly obtain the attribute
Pull out individual attributes from the object to ensure that the data is responsive
Syntax format:
import { toRef } from 'vue'
export default {
const obj = {
msg: 'hello'
}
const msg = toRef(obj,'msg')
setup() {
return {msg}
}
}
Copy the code
Code demo:
<template>
<div>
<div>{{ msg }}</div>
<div>{{ info }}</div>
<button @click="handleClick"</button> </div> </template> <script> import {reactive, toRef} from'vue'
export default {
name: 'App'.setup() {
const obj = reactive({
msg: 'hello',
info: 'Leo'
})
const msg = toRef(obj, 'msg')
const info = toRef(obj, 'info')
const handleClick = () => {
obj.msg = 'hi'
}
return { msg, info, handleClick }
}
}
</script>
<style lang="less"></style>
Copy the code
Conclusion: toRef method can extract single attribute from object and ensure responsiveness
3. ToRefs function
Syntax format:
import { toRefs } from 'vue'
export default {
setup() {
const obj = reactive({
msg: 'hello'.info: 'Leo'
})
// deconstruct the attributes in obj
const {msg,info} = toRefs(obj)
return {msg, info}
}
}
Copy the code
Conclusion: toRefs is a method that can batch convert properties in objects to independent responsive data
4. Ref function
It is used to define common (basic) data and ensure responsiveness
Syntax format:
import {ref} from 'vue'
export default {
setup () {
const count = ref(0)
const handleClick = () = > {
// the value attribute is used when operating in js
count.value += 1}}}Copy the code
Code demo:
<template>
<div>
<div>{{ count }}</div>
<button @click="handleClick"</button> </div> </template> <script> import {ref} from'vue'
export default {
name: 'App'.setup() {const count = ref(0) const handleClick = () => {// count += 1}return { count, handleClick }
}
}
</script>
<style lang="less"></style>
Copy the code
Conclusion:
- If it is primitive type data, you can define it using ref
- Ref can actually define an object, but the value attribute is required to access it
conclusion
- Normal data returned directly from SETUP is not reactive
- Wrapping objects around Reactive can be called reactive data
- To simplify access to objects (without prefixes), optimization can be done using toRef
- To get multiple properties in an object, you can use toRefs to simplify things further
- For simple data types, the ref definition is more appropriate
5. Computed attributes
Note: Computed properties in VUe3 are also composed API style
- The callback must return, and the result is the result of the calculation
- If the data on which the calculated property depends changes, the calculation is recalculated
- Do not perform asynchronous operations in computed properties
- Modifies the value of the calculated property
Sample code:
<template> <div> This year: {{age}} age <br /> Next year: {{nextAge}} age <br /> < button@click ="nextAge = 28"> Click </button> </div> </template> <script> import {ref, computed} from'vue'
export default {
name: 'App'.setupConst age = ref(0) // read-only // const nextAge = computed(() => {//returnValue + 1 //}) const nextAge = computed({get() {
return age.value + 1
},
set(v) {
age.value = v - 1
}
})
return { age, nextAge }
}
}
</script>
<style lang="less"></style>
Copy the code
Conclusion:
- Calculated properties can be read or modified directly
- If you want to implement modification operations for computed properties, the computed arguments should be objects
- Reading data triggers the GET method
- Modifying data triggers the set function, which takes the assigned value as its parameter
6. Watch listener
Triggers a listener callback when the information being listened for changes
Typical scenario: After route parameters change, the interface is invoked again to obtain component data
- Listen for reactive data defined by ref
Syntax format:
import {ref, watch} from 'vue'
export default {
setup() {
const count = ref(0)
// Listen for data changes based on listeners
// The audit office to be monitored must be responsive
watch (count, (newVal,oldVal) = > {
// newVal indicates the modified value
// oldVal indicates the value before modification
console.log(newVal,oldVal)
})
return {count}
}
}
Copy the code
Summary: Listening for normal data can get the value before and after modification. The data being listened must be responsive
- Listen for reactive data defined by Reactive
Syntax format:
import {reactive, watch} from 'vue'
export default {
setup () {
const obj = reactive({
msg: 'tom'
})
watch(obj,() = > {
// Get the latest value directly
console.log(obj)
})
}
}
Copy the code
Conclusion: If you are listening on an object, then the two arguments to the listener’s callback function are the same result, representing the latest object data. In this case, the listener can also be read directly, and the value is also the latest.
- Listen for multiple responsive data
Syntax format:
import {ref, watch} from 'vue'
export default {
setup () {
const n1 = ref(1)
const n2 = ref(2)
watch ([n1, n2], (v) = > {
// v represents the latest value of all data being listened on, of type array
console.log(v)
})
const handleClick = () = > {
n1.value = 3
n2.value = 4
}
return {n1, n2}
}
}
Copy the code
Conclusion:
- You can get the values before and after the update
- The result of listening is also an array of data in the same order
- Listen to a property of reactive data defined by Reactive
Syntax format:
<template> <div> name: {{user.name}}<br /> Year: {{user.age}} age <br /> < button@click ="user.age = 13"</button> </div> </template> <script> import {reactive, watch} from'vue'
export default {
name: 'App'.setup() {
const user = reactive({
name: 'Ming',
age: 12
})
watch(
() => user.age,
v => {
console.log(v)
}
)
return { user }
}
}
</script>
<style lang="less"></style>
Copy the code
Conclusion:
- If you are listening for a property in an object, you need to use the function method
- Listening for less data improves performance
- Watch configuration items
Syntax format:
import {} from 'vue'
export default {
setup () {
// immediate: true Indicates that the component is triggered immediately after rendering
watch(() = > stuInfo.friend, () = > {
console.log('stuInfo')
},{
immediate: true.// What is being listened on needs to be written as a function
deep: true // Deep listening}}})Copy the code
Conclusion:
- Immediate: true, indicates the history call during component rendering
- Deep: true: indicates a subproperty of a deep listening object (the object being listened on needs to be a function)
7. Ref attribute
To obtain a DOM or component instance, you can use the ref attribute, which is separate from Vue2.0
Vue2 rules in
Conclusion:
- Vue2 allows direct manipulation of individual DOM and components via ref
- In VUe2, DOM and components can be manipulated in batches via refs
Vue3 rules in
-
Ref operates on a single DOM element
Code demo:
<template> <div> <div ref="info">hello</div> <button @click="handleClick"</button> </div> </template> <script> import {ref} from'vue' export default { name: 'App'.setup() {const info = ref(null) const handleClick = () => { // You can use info.value.innerhtml to print the contents of the DOM console.log(info.value.innerhtml)}return { info, handleClick } } } </script> <style lang="less"></style> Copy the code
Summary: The flow of manipulating a single DOM or component
- Define a reactive variable
- Return the variable to the template for use
- Bind the above returned data in the template
- You can manipulate the DOM or components through variables
-
The batch operation
Code demo:
<template> <div> <ul> <li :ref="setFruits" v-for="item in fruits" :key="item.id">{{ item.name }}</li> </ul> <button @click="handleClick"</button> </div> </template> <script> import {ref} from'vue' export default { name: 'App'.setup() { const fruits = ref([ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'pear'}]) const arr = [] const setFruits = el => {// el represents a single DOM element arr.push(el.innerhtml)} const handleClick = () => { console.log(arr) }return { fruits, handleClick, setFruits } } } </script> <style lang="less"></style> Copy the code
Summary: the flow of ref batch manipulating elements
- Define a function
- Bind this function to ref (must be bound dynamically)
- In a function, you get a single element as an argument, and that element can be placed in an array
1. Define a function 2. Bind the function to ref (** must dynamically bind **) 3. In a function, you can get a single element as an argument. This element can normally be placed in an array. Batch elements can be manipulated through the array aboveCopy the code
8. Father-son communication
Vue2 writing
- Parent component passes data to child component: custom property props
- Child component passes data to parent component: custom event $emit()
Vue3 writing
The parent passes value to the child
steps
- The setup function return
- The subcomponent props receives
Code demo
If you want setup in a child component, pass in the parameter setup
Note: The props value is read-only and cannot be modified directly in a child component
- The parent component
<template> <div> Parent <hr> <son :money="money"></son>
</div>
</template>
<script>
import Son from './Son.vue'
import { ref } from 'vue'
export default {
name: 'App'.setup () {
const money = ref(100)
return { money }
},
components: {
Son
}
}
</script>
<style lang="less">
</style>
Copy the code
- The child components
Custom attributes can be used directly in templates
< the template > < div > child components -- -- -- -- -- {{money}} < / div > < / template > < script >export default {
name: 'Son',
props: {
money: {
type: Number,
default: 0
}
},
setup (props) {
console.log(props.money)
}
}
</script>
<style>
</style>
Copy the code
js
Need to write the following code
setup(props) {
const getMoney = () = > {
console.log(props.xxx)
}
return { getMoney }
}
Copy the code
Conclusion:
- Property values in props can be obtained directly from the subcomponent template
- You need to get it from the first parameter in setup in your js code
Children pass values to their parents
steps
- Child component
setup
The second parameter passed in throws a custom event to the parent component - Define custom events in the parent component to complete the following operations
Code demo
- The child components
Setup also has a second parameter, whose name can be customized
Note: emits must be written, do not write vue will have the following warning. If there are other custom events, you can continue to add them to the array.
<template> <div> child component -----{{money}}</div>+
</template>
<script>
export default {
name: 'Son',
+ emits: ['sendToPar']
props: {
money: {
type: Number,
default: 0
}
},
+ setup (props, context) {
console.log(props.money)
+ const handleClick = () => {
+ context.emit('sendToPar', 50)
+}
+ return { handleClick }
}
}
</script>
<style>
</style>
Copy the code
Conclusion:
- A custom event is emitted via the context.emit method as argument 2 to the setup function
context.emit('xxx',xx)
- Custom events triggered by sub-components need to be declared in the emits option to see which custom events are triggered by the component
- The parent component
<template> <div> Parent component <hr>+
</div>
</template>
<script>
import Son from './Son.vue'
import { ref } from 'vue'
export default {
name: 'App',
setup () {
const money = ref(100)
+ const getMoney = (val) => {
console.log(val)
+ money.value = money.value - val
+}
+ return { money, getMoney }
},
components: {
Son
}
}
</script>
<style lang="less">
</style>
Copy the code
Dependency injection
Usage scenario: There is a parent component, which has child components, descendant components, there are many descendant components, share the parent component data
The parent component passes data to the descendant component
steps
- Used in the parent component
provide
Pass out data - Use of descendant components
inject
Receives data from the ancestor component
Code demo
- The parent component
Dojo.provide – >
<template> <div> parent <hr> <son :money="money" @sendtopar ="getMoney"></son> </div> </template> <script> import son from './Son.vue'+import { ref, provide } from 'vue'Export default {name: 'App', setup () {const money = ref(100) // Pass data to descendant components+ provide('moneyInfo', 1000)// Const getMoney = (val) => {console.log(val) money.value = money.value - val} return {money, getMoney } }, components: { Son } } </script> <style lang="less"> </style>Copy the code
- in
Child components
To register descendant components in
< the template > < div > child components -- -- -- -- -- {{money}} < / div > < button @ click = "handleClick" > click < / button > < hr >+
</template>
<script>
+import GrandSon from './GrandSon.vue'
export default {
name: 'Son',
emits: ['sendToPar'],
props: {
money: {
type: Number,
default: 0
}
},
setup (props, context) {
console.log(props.money)
const handleClick = () => {
context.emit('sendToPar', 50)
}
return { handleClick }
},
+ components: {
+ GrandSon
+}
}
</script>
<style>
</style>
Copy the code
- Sons of components
Inject – > injection
<template> <div> Grandson component -----{{money}}</div> </template> <script> import {inject} from'vue'
export default {
name: 'GrandSon'.setup () {
const money = inject('moneyInfo')
return { money }
}
}
</script>
<style>
</style>
Copy the code
Conclusion:
- Parental descendant data: Use provide
- Grandchildren get data: use Inject
Descendant components pass data to parent components
steps
- The ancestor component passes a function to the descendant component
- The descendant component receives and passes an argument to the ancestor component
Code demo
- The parent component
Pass a function to the descendant component
<template> <div> parent <hr> <son :money="money" @sendtopar ="getMoney"></son> </div> </template> <script> import son from './Son.vue' import { ref, provide } from 'vue' export default { name: 'App', setup () {const money = ref(100) // Pass a function to descendant components+ const handleMoney = (val) => {
+ console.log(' data passed back by descendant component ', val)
+}
+ provide('handleMoney', handleMoney)// Const getMoney = (val) => {console.log(val) money.value = money.value - val} return {money, getMoney } }, components: { Son } } </script> <style lang="less"> </style>Copy the code
- Sons of components
<template> <div> grandchild component+
</div>
</template>
<script>
import { inject } from 'vue'
export default {
name: 'GrandSon',
setup () {
+ const handleMoney = inject('handleMoney')
+ const handleSend = () => {
+ handleMoney(200)
+}
+ return { handleSend }
}
}
</script>
<style>
</style>
Copy the code
Summary: The child component passes data to the parent component by providing a function
- The grandparent component passes a function and then retrieves data from the function’s parameters
- The grandson component gets and calls this function to pass the data
10. Do things
V – model syntactic sugar
Review of vue2 use
V-model is the syntax sugar for value and @input
The essence is a combination of attribute binding and event binding
<input type="text" :value="uname" @input="uname=$event.target.value">
- V-models can also be used on components
<my-com v-model="info"></my-com>
<my-com :value="info" @input="info=$event"></my-com>
Copy the code
- If it is a native DOM event, then $event represents the js native event object
- If it is a component custom event, then $event is the data that #emit passes
Summary: Application scenarios of V-Model in VUe2
- Used on form elements: $event represents the event object
- Used on components: $event represents data passed by child components
New v-Model features in VUE3
The essence of v-Model is the binding of modelValue and @update:modelValue
Code demo
- The parent component
<template> <div> Parent component {{info}} {{MSG}} <hr> <text-event V-model :modelValue="info" v-model:msg="msg"></text-event> <! --> <! -- <text-event :modelValue="info" @update:modelValue="info=$event" /> -->
</div>
</template>
<script>
import { ref } from 'vue'// Import TextEvent from'./TextEvent.vue'
export default {
name: 'App', components: {// register component TextEvent},setup () {
const info = ref('hi~')
const msg = ref('Leo')
return { info, msg }
}
}
</script>
Copy the code
- Child components
Gets the value passed by the parent component
<template> <div> child component {{modelValue}} {{MSG}} < button@click ="handleClick"</button> </div> </template> <script>export default {
name: 'TextEvent',
props: {
modelValue: {
type: String,
default: ' '
},
msg: {
type: String,
default: ' '
}
}
}
</script>
Copy the code
Modifies the value passed by the parent component
<template> <div> subcomponent {{modelValue}} {{MSG}} < button@click ="handleClick"> Click </button> </div> </template> <script> export default { name: 'TextEvent', props: { modelValue: { type: String, default: '' }, msg: { type: String, default: '' } },+ setup (props, context) {
+ const handleClick = () => {
+ context.emit('update:modelValue', 'hello')
+ context.emit('update:msg', 'leo')
+}
+ return { handleClick }
+}
}
</script>
<style>
</style>
Copy the code
Conclusion:
- V-models can pass multiple values to child components by binding multiple properties and ensure bidirectional binding
- Can replace vue2
.sync
Modifier (sync modifier is deprecated in VUe3)
conclusion
This series will continue to be updated, if you help my friends, please remember to like + bookmark oh ~