Table of contents
The difference between vue2 and vue3 variables
4. Get label elements or components
2. The difference between ref and toRef
Seven, shallowReactive shallow reactive
2, shallow reactive of shallow reactive
2. The difference between watchEffect and watch
1. setup function
<template>
<div id="app">
<p>{
{ number }}</p>
<button @click="add">增加</button>
</div>
</template>
<script>
// 1. 从 vue 中引入 ref 函数
import {ref} from 'vue'
export default {
name: 'App',
setup() {
// 2. 用 ref 函数包装一个响应式变量 number
let number = ref(0)
// 3. 设定一个方法
function add() {
// number是被ref函数包装过了的,其值保存在.value中
number.value ++
}
// 4. 将 number 和 add 返回出去,供template中使用
return {number, add}
}
}
</script>
The difference between vue2 and vue3 variables
1. To access variables in data or props in vue2, you need to use this
2. The setup function of vue3 has two parameters, namely props and context
(1) props: store and define the parameter names and parameter values that the current component allows to pass from the outside world
(2) context: context object, from which attr, emit, slots can be accessed
[emit is the communication method of the parent component in vue2, which can be called directly]
2. Life cycle
View 2 |
View 3 |
---|---|
beforeCreate |
setup |
created |
setup |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeDestory |
onBeforeUnmount |
destoryed |
onUnmounted |
The use of the vue3 life cycle is also imported from vue first, and then directly called
<template>
<div id="app"></div>
</template>
<script>
// 1. 从 vue 中引入 多个生命周期函数
import {onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, unMounted} from 'vue'
export default {
name: 'App',
setup() {
onBeforeMount(() => {
// 在挂载前执行某些代码
})
onMounted(() => {
// 在挂载后执行某些代码
})
onBeforeUpdate(() => {
// 在更新前前执行某些代码
})
onUpdated(() => {
// 在更新后执行某些代码
})
onBeforeUnmount(() => {
// 在组件销毁前执行某些代码
})
unMounted(() => {
// 在组件销毁后执行某些代码
})
return {}
}
}
</script>
Three, reactive method
Used to create a responsive data object, this API also solves the defect of Vue2 by implementingdefineProperty
data responsiveness
<template>
<div id="app">
<!-- 4. 访问响应式数据对象中的 count -->
{
{ state.count }}
</div>
</template>
<script>
// 1. 从 vue 中导入 reactive
import {reactive} from 'vue'
export default {
name: 'App',
setup() {
// 2. 创建响应式的数据对象
const state = reactive({count: 3})
// 3. 将响应式数据对象state return 出去,供template使用
return {state}
}
}
</script>
Fourth, the ref method
1 Introduction
Wraps a responsive data object, ref is by reactive
wrapping an object, and then passing the value to value
the property in the object
Note: .value is only needed when accessing the ref method, but not in the template template
2. use
It can be simply ref(obj)
understood as this reactive({value: obj})
<script>
import {ref, reactive} from 'vue'
export default {
name: 'App',
setup() {
const obj = {count: 3}
const state1 = ref(obj)
const state2 = reactive(obj)
console.log(state1)
console.log(state2)
}
}
</script>
3. ref and reactive
(1) Basic type values (string, number, boolean, etc.) or single-value objects (like {count:3} with only one attribute value) use ref
(2) Reference type values (object, array) use reactive
4. Get label elements or components
(1) In Vue2, we get elements by giving them an ref
attribute and then this.$refs.xx
accessing them, which is no longer applicable in Vue3
(2) Vue3 obtains elements as follows
<template>
<div>
<div ref="el">div元素</div>
</div>
</template>
<script>
import {ref,onMounted} from 'vue'
export default {
name: "SetupView",
setup() {
// 创建一个DOM引用,名称必须与元素的ref属性名相同
const el = ref(null)
// 在挂载后才能通过el获取到目标元素
onMounted(()=>{
el.value.innerHTML = '内容被修改'
})
// 把创建的引用return出去
return {el}
},
};
</script>
(3) Operation steps to obtain elements:
Supplement: The set element reference variable can only be accessed after the component is mounted, so it is invalid to operate on the element before mounting
Five, toRef
1 Introduction
Convert a value in an object into responsive data , which receives two parameters
(1) The first parameter is obj
an object
(2) The second parameter is the attribute name in the object
<template>
<div>
<div> {
{ state }} </div>
</div>
</template>
<script>
import { toRef } from "vue";
export default {
name: "SetupView",
setup() {
const obj = { count: 3 };
const state = toRef(obj, "count"); //注意:count有加单引号
return { state };
},
};
</script>
2. The difference between ref and toRef
The above example ref can also be implemented, so why do we need toRef? Let’s take a look at their differences.
<template>
<div>
<p>{
{ state1 }}</p>
<button @click="add1">增加1</button>
<p>{
{ state2 }}</p>
<button @click="add2">增加2</button>
</div>
</template>
<script>
import { ref,toRef } from "vue";
export default {
name: "SetupView",
setup() {
const obj = {count:3}
const state1 = ref(obj.count)
const state2 = toRef(obj,'count')
function add1(){
state1.value++
console.log('ref原始值:',obj);
console.log('ref响应式',state1);
}
function add2(){
state2.value++
console.log('toRef原始值:',obj);
console.log('toRef响应式',state2);
}
return {state1,state2,add1,add2}
},
};
</script>
(1) ref is a copy of the incoming data; toRef is a reference to the incoming data
(2) The ref value will change and update the view; the change of toRef value will not update the view
Six, toRefs
Convert the values of all attributes in the incoming object into responsive data objects. This function supports one parameter, the obj
object
<template>
<div>
<div>{
{ state }}</div>
</div>
</template>
<script>
import { toRefs } from "vue";
export default {
name: "SetupView",
setup() {
const obj={
name:'前端学学学',
age:18,
gender:0
}
const state = toRefs(obj)
console.log(state);
},
};
</script>
Seven, shallowReactive shallow reactive
1 Introduction
The obj object passed to reactive by shallowReactive has more than one layer, so it will be wrapped with Proxy every time
<template>
<div>
<div>{
{ state }}</div>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "SetupView",
setup() {
const obj={
a:1,
first:{
b:2,
second:{
c:3
}
}
}
const state = reactive(obj)
console.log(state);
console.log(state.first);
console.log(state.first.second);
},
};
</script>
If an object has a deep hierarchy, wrapping each layer Proxy
is very unfriendly to performance
2, shallow reactive of shallow reactive
shallowreactive Only the first layer is processed by Proxy, that is, only when the value of the first layer is modified, will it be updated responsively
<template>
<div>
<div>{
{ state.a }}</div>
<div>{
{ state.first.b }}</div>
<div>{
{ state.first.second.c }}</div>
<button @click="change1">改变1</button>
<button @click="change2">改变2</button>
</div>
</template>
<script>
import { shallowReactive } from "vue";
export default {
name: "SetupView",
setup() {
const obj={
a:1,
first:{
b:2,
second:{
c:3
}
}
}
const state = shallowReactive(obj)
function change1(){
state.a = 7
}
function change2(){
state.first.b = 8
state.first.second.c =9
console.log(state);
}
return {state,change1,change2}
},
};
</script>
Eight, shallowRef
1 Introduction
Shallow ref is also used for performance optimization
(1) shallowReactive
It is to monitor the data changes of the first layer of the object to drive the view update
(2) shallowRef
It is .value
the change of the monitored value to update the view
(3) Code example
<template>
<div>
<div>{
{ state.a }}</div>
<div>{
{ state.first.b }}</div>
<div>{
{ state.first.second.c }}</div>
<button @click="change1">改变1</button>
<button @click="change2">改变2</button>
</div>
</template>
<script>
import { shallowRef } from "vue";
export default {
name: "SetupView",
setup() {
const obj={
a:1,
first:{
b:2,
second:{
c:3
}
}
}
const state = shallowRef(obj)
console.log(state);
function change1(){
state.value ={
a:7,
first:{
b:8,
second:{
c:9
}
}
}
}
function change2(){
state.value.first.b = 4
state.value.first.second.c = 5
console.log(state);
}
return {state,change1,change2}
},
};
</script>
① Click the second button to change the data but the view does not change
②The first button will .value
reassign the entire value, and the view will be updated
2、triggerRef
triggerRef
It can solve the problem of the second button in the above example, and the view can be updated immediately, which receives a parameter , that is, the object state
to be updated ref
<template>
<div>
<div>{
{ state.a }}</div>
<div>{
{ state.first.b }}</div>
<div>{
{ state.first.second.c }}</div>
<button @click="change">改变</button>
</div>
</template>
<script>
import { shallowRef,triggerRef } from "vue";
export default {
name: "SetupView",
setup() {
const obj={
a:1,
first:{
b:2,
second:{
c:3
}
}
}
const state = shallowRef(obj)
console.log(state);
function change(){
state.value.first.b = 4
state.value.first.second.c = 5
triggerRef(state)
console.log(state);
}
return {state,change}
},
};
</script>
Nine, toRaw method
toRaw
method is used to get ref
or reactive
object's raw data
<template>
<div>
<div>{
{ state.name }}</div>
<div>{
{ state.age }}</div>
<button @click="change">改变</button>
</div>
</template>
<script>
import { reactive,toRaw } from "vue";
export default {
name: "SetupView",
setup() {
const obj={
name:'前端学学学',
age:18,
}
const state = reactive(obj)
const raw = toRaw(state)
function change(){
state.age = 90
console.log(obj);
console.log(state);
console.log(obj === raw);
}
return {state,change}
},
};
</script>
The above code proves that toRaw
the method reactive
obtains the original data from the object, so we can easily do some performance optimization by modifying the value of the original data without updating the view
Note: Add a sentence, when toRaw
the parameter received by the method is ref
an object, it needs to be added .value
to get the original data object
10. markRaw
markRaw
The method can mark the original data as non-responsive, even if it is used ref
or reactive
packaged, it still cannot achieve data responsiveness. It receives a parameter, that is, the original data, and returns the marked data
<template>
<div>
<div>{
{ state.name }}</div>
<div>{
{ state.age }}</div>
<button @click="change">改变</button>
</div>
</template>
<script>
import { reactive, markRaw } from "vue";
export default {
name: "SetupView",
setup() {
const obj = {
name: "前端学学学",
age: 18,
};
// 通过markRaw标记原始数据obj, 使其数据更新不再被追踪
const raw = markRaw(obj);
// 试图用reactive包装raw, 使其变成响应式数据
const state = reactive(raw);
function change() {
state.age = 90;
console.log(state);
}
return { state, change };
},
};
</script>
markRaw
The data processed by the method cannot be packaged reactive
into responsive data, and the view will not be updated if the value is modified, that is, data responsiveness is not implemented
Eleven, provide && inject
1 Introduction
- provide : Pass data to child components and descendant components. Receive two parameters, the first parameter is
key
the name of the data; the second parameter isvalue
the value of the data - inject : Receive the data passed by the parent component or ancestor component. Receive a parameter
key
, which is the name of the data passed by the parent component or ancestor component
2. Code example
Suppose there are three components, namely A.vue
, B.vue
, C.vue
, where B.vue
is A.vue
the subcomponent, and C.vue
is B.vue
the subcomponent
// A.vue
<script>
import {provide} from 'vue'
export default {
setup() {
const obj= {
name: '前端印象',
age: 22
}
// 向子组件以及子孙组件传递名为info的数据
provide('info', obj)
}
}
</script>
// B.vue
<script>
import {inject} from 'vue'
export default {
setup() {
// 接收A.vue传递过来的数据
inject('info') // {name: '前端印象', age: 22}
}
}
</script>
// C.vue
<script>
import {inject} from 'vue'
export default {
setup() {
// 接收A.vue传递过来的数据
inject('info') // {name: '前端印象', age: 22}
}
}
</script>
Twelve, watch && watchEffect
watch
Both watchEffect
are used to monitor a data change to perform a specified operation, but there are still differences in usage
1. Introduction to watch
watch format: watch( source, cb, [options])
- source: It can be an expression or a function, which is used to specify the dependent object to monitor
- cb: the callback function executed after the dependent object changes
- options: can be parameterized, and the attributes that can be configured include immediate (immediately trigger the callback function), deep (deep monitoring)
(1) When listening to the ref type:
<script>
import { ref, watch } from "vue";
export default {
name: "SetupView",
setup() {
const state = ref(0);
watch(state, (newValue, oldValue) => {
console.log(`原值${oldValue}`);
console.log(`新值${newValue}`);
});
// 1秒后值+1
setTimeout(() => {
state.value++;
}, 1000);
},
};
</script>
(2) When listening to the reactive type:
<script>
import { reactive, watch } from "vue";
export default {
name: "SetupView",
setup() {
const state = reactive({count:0});
watch(()=>state.count,(newValue,oldValue)=>{
console.log(`原值${oldValue}`);
console.log(`新值${newValue}`);
});
// 1秒后值+1
setTimeout(() => {
state.count++;
}, 1000);
},
};
</script>
(3) When monitoring multiple values at the same time:
<script>
import { reactive, watch } from "vue";
export default {
name: "SetupView",
setup() {
const state = reactive({count:0,name:'23'});
watch([()=>state.count,()=>state.name],([newCount,newName],[oldCount,oldName])=>{
console.log(oldCount);
console.log(newCount);
console.log(oldName);
console.log(newName);
});
// 1秒后值+1
setTimeout(() => {
state.count++;
state.name = 'sxx'
}, 1000);
},
};
</script>
(4) Because watch
the first parameter of the method has already specified the object to monitor, when the component is initialized, the callback function in the second parameter will not be executed. If we want it to be initialized , we can execute it first . Set in the third parameter object immediate: true
(5)watch
The default method is to gradually monitor the data we specify. For example, if the monitored data has multiple layers of nesting, deep data changes will not trigger the monitoring callback. If we want it to also monitor the deep data, we can do it in the third set in a parameter object deep: true
(6) The watch method will return a stop method. If you want to stop monitoring , you can directly execute the stop function
2、watchEffect
watch
difference with
(1) No need to manually import dependencies
(2) A callback function will be executed every time it is initialized to automatically obtain dependencies
(3) The original value cannot be obtained, only the changed value can be obtained
<script>
import { reactive, watchEffect } from "vue";
export default {
name: "SetupView",
setup() {
const state = reactive({count:0,name:'23'});
watchEffect(()=>{
console.log(state.count);
console.log(state.name);
})
// 1秒后值+1
setTimeout(() => {
state.count++;
state.name = 'sxx'
}, 1000);
},
};
</script>
Instead of watch
passing in a dependency to it like a method, it directly specifies a callback function
When the component is initialized, the callback function will be executed once, and the data that needs to be detected will be automatically obtained
Thirteen, getCurrentInstance
<template>
<div>
<div>{
{ num }}</div>
</div>
</template>
<script>
import { ref,getCurrentInstance } from "vue";
export default {
name: "SetupView",
setup() {
const num = ref(3)
const instance = getCurrentInstance()
console.log(instance);
return {num}
},
};
</script>
1. Output value ctx
2. Output value proxy
ctx
The content of and proxy
is very similar, except that the latter has a layer of external packaging relative to the former proxy
, so it can be explained proxy
that it is responsive
Fourteen, useStore
Through the useStore method in vuex
// store 文件夹下的 index.js
import Vuex from 'vuex'
const store = Vuex.createStore({
state: {
name: '前端印象',
age: 22
},
mutations: {
……
},
……
})
// example.vue
<script>
// 从 vuex 中导入 useStore 方法
import {useStore} from 'vuex'
export default {
setup() {
// 获取 vuex 实例
const store = useStore()
console.log(store)
}
}
</script>