1.composition API 和Option API可以混合使用
composition API本质(组合API/注入API)
2.setup执行时机
beforeCreate:表示组件刚刚被创建出来,组件的data和 methods还没有被初始化好
setup//原文写的是around and两者之间,就是围绕俩者产生的,也不一定就是在他们中间,只是这样好理解些,表示俩者里面的data,methods这些在setup里面不被支持
Created:表示组件刚刚被创建出来,并且组件的data和methods已经初始化好set
注意点:
1)由于在执行setup函数的时候,还没有执行created生命周期的方法,
所以在setup中还不能使用data和methods
2)由于我们不能再setup函数中使用data和methods,
所以vue为了避免我们错误的使用,它直接将setup函数中this修改成了undefined
3)setup函数只能是同步的,不能是异步的
3.详解reactive和ref
reactive是vue3中提供的实现响应式数据的方法
在vue2中响应式数据是通过defineProperty来实现的
而在vue3中响应式是通过ES6的proxy来实现的
注意点:
1)reactive参数biubiu是对象(json/arr)
2)如果给reactive传递了其它对象
默认情况下修改对象,界面不会自动更新
如果想更新,可以通过重新赋值的方式
不是对象的时候就无法实现响应式,案例如下
<template>
<div>
<p>{{state}}</p>
<button @click="myFn">按钮</button>
</div>
</template>
<script>
import {reactive} from 'vue'
export default {
name: 'App',
setup(){
// 创建一个响应式数据
// 本质:就是将传入的数据包装成一个proxy对象
let state= reactive(123);
function myFn(){
state=321; //由于在创建响应式数据的时候,传递的不是一个对象,所以没法实现响应式
console.log(state)//打印出了321,但是页面上没改变
}
return {state,myFn};
}
}
</script>
所以为了实现一个变量也能实现,引入ref
ref的本质就是reactive对象有个value属性
那么vue在使用变量时是如何决定是否自动添加.value的
vue在解析数据之前,会自动判断这个数据是否是ref类型,
通过当前数据的_ _v_ref来判断的
如果有这个私有属性,并且取值为true,那么就代表是一个ref类型的数据
我们也可以手动判断
import {isRef isReactive} from 'vue'
console.log(isRef(age))
console.log(isReactive(age))
递归监听
let statte = reactive({
a:'a',
b:{
c:'c',
d:{
e:'e'
}
}
})
function myfn(){
state.a='1';
state.b.c='2';
state.b.c.e='3';
}
结果是可以改变的,意味着是可以监听的,
1)默认情况下,无论是通过ref还是reactive都是递归监听
2)存在问题,如果数据量比较大,非常消耗性能
3)非递归监听
shallowReactive shallowRef
import {shallowReactive} from 'vue';
import {shallowRef} from 'vue';
let statte = reactive({
a:'a',
b:{
c:'c',
d:{
e:'e'
}
}
})
function myfn(){
state.a='1';//只有第一层转化proxy对象 在改变第一层的时候刷新ui其他值也会发生改变
state.b.c='2';// 第一层不改变,这里改变的时候数据监听不到
state.b.c.e='3';
}
注意点: 如果是通过shallowRef创建数据,那么vue监听的是.value的变化,并不是第一层的变化
function myfn(){
state.value={
a:'a',
b:{
c:'c',
d:{
e:'e'
}
}
}
}
那么就有一个问题,我们只改变第四层,又想改变怎么办
import {triggerRef} from 'vue';
state.value.a.b.c='1'
triggerRef(state)//注意点,vue3只提供了triggerRef方法,没有提供triggerReactive,所以reactive用不到,哈哈哈
toRaw
ref/reactive数据类型的特点
每次修改都会被追踪,都会更新UI界面,到那时这样其实是非常消耗性能的
所以每次如果我们有一些操作不被追踪,不需要更新Ui界面,那么这个时候,
我们就可以通过toRaw方法拿到它的原始数据,对原始数据进行修改
这样就不会被追踪,这样就不会更新UI界面
let obj={name:'yk',age:18}
let state=reactive(obj);
let obj2=toRaw(state);
console.log(obj===state)//false
console.log(obj===obj2)//true
toRef
let obj={name:''yl};
let state=ref(obj.name);
function myFn(){
state.value='zs';
console.log(obj);//{name:''yl};
console.log(state);//{value:'zs'}
}
结论:如果利用ref将某一个对象中的属性变成响应式的数据,我们修改响应式的数据不会影响到原始数据的
所以引入toRef
import {toRef} from 'vue'
结论:如果利用toRef将某一个对象中的属性变成响应式的数据我们修改响应式的数据是不会影响到原始数据的