一、setup函数 setup:一般返回一个对象,对象的key可以直接使用(也可以返回一个渲染函数)
二、ref函数 创建一个响应值:ref(“张三”),ref({ name:“张三” }),返回一个RefImpl对象(引用实现的实例化对象,简称引用对象,也叫ref对象)
操作基础类型的响应值:ref(“张三”).value,ref(“张三”).value = https://www.it610.com/article/“李四”
操作引用类型的响应值:ref({ name:“张三” }).value.name,ref({ name:“张三” }).value.name = “李四”
重点:ref函数返回的是ref对象,当创建的是基础类型的响应式是使用的是object.defineproperty的get与set方法进行数据劫持;当创建的是引用类型时使用的是ES6里面的 Proxy对象 进行代理实现的(实际上是求助了reactive函数)
三、reactive函数 作用:定义一个对象类型的响应式数据(基础类型不能用它)
创建一个响应值:const 代理对象 = reactive(源对象),返回一个代理对象(Proxy的实例化对象,简称Proxy对象)
操作响应值:reactive({ name:“张三” }).name,reactive({ name:“张三” }).name = “李四”
四、回忆vue2 的响应式 【vue3|vue3.0常用的composition API】1. 实现原理
- 对象类型:进行递归遍历对象的属性进行object.defineproperty的数据劫持
- 数组类型:通过重写更新数组的一系列方法来进行实现拦截。(对数组的变更方法进行包裹)
- 新增,删除属性时,界面不会更新
- 直接通过下标修改数组,界面不会更新
- 得采用 s e t , set, set,delete,splice等方式进行修改
- 通过Proxy(代理):拦截对象中任意属性的变化
- 通过Reflect(反射):对源对象的属性进行操作(好处是Reflect不会直接抛错)
const data = https://www.it610.com/article/{
name:"haonan"
}
const proxy = new Proxy(data, {
//拦截读取属性
get(target,prop){
return Reflect.get(target,prop)
},
//拦截修改和新增属性
set(target,prop,value){
return Reflect.set(target,prop,value)
},
//拦截删除属性
defineProperty(target,prop){
return Reflect.defineProperty(target,prop)
},
})proxy.name = "henry"
五、setup的两个注意点 setup执行的时机:在beforeCreate之前执行一次,this是undefined
setup的参数:
- props:值为Proxy对象,包含 组件外部传递过来,且组件内部声明接收了的属性
- context:上下文对象
attrs:值为对象,包含 组件外部传递过来,但没有在props内部声明的属性,相当于vue2中的六、计算属性与监视 1.computed函数this.$attrs
。
slots:收到的插槽内容,相当于this.$slots
。(vue3中得写成v-slot:
,不要写成solt=""
)
emit:分发自定义事件的函数,相当于this.$emit
。
import { computed,reactive } from "vue";
setup() {
const user = reactive({
firstName: "张",
lastName: "三",
});
//简写
user.fullName = computed(() => {
return user.firstName + "-" + user.lastName;
});
//完整写法
user.fullName = computed({
set(value){
const arr = value.split('-')
user.firstName = arr[0]
user.lastName = arr[1]
},
get(){
return user.firstName + "-" + user.lastName;
}
});
return {
user,
};
},
2.watch函数 需要注意:
- 监听reactive定义的响应式数据时:oldValue无法正确获取、且是强制的深度监听(deep配置失效)
- 监听reactive定义的响应式数据中的某个属性时:不会深度监听,deep配置依旧有效
- 当监听的是reactive定义的响应式数据中的某个属性时,需要使用
()=>
包裹监听的数据属性
const user = reactive({
name:"henry",
job:{
c:'1',
a:{
b:222
}
}
})
watch(user,(newval,oldval)=>{
console.log('user',newval,oldval)
},{
immediate:true,//有效
deep:false //无效,当监听的对象是Proxy对象时,强制开启深度监听,且无法正确获取oldVal
})
watch([()=>user.name,()=>user.job.a.b],(newval,oldval)=>{//多个监听时,可以用数组的形式
console.log('名称和薪资有更新',newval,oldval)
})
watch(()=>user.name,(newval,oldval)=>{//当你监听的是对象的属性,并且是一个基础类型时,一定得用'()=>'的方式监听
console.log('名称有更新',newval,oldval)
})
watch(()=>user.job,(newval,oldval)=>{//当你监听的是对象的属性,并且该属性的值是一个对象时,可用可不用'()=>'的方式监听,此时不会开启深度监听,需要配置deep才能开启深度监听
console.log('job有更新',newval,oldval)
},{
deep:true
})
当使用ref创建对象类型的数据时,由于ref内部是求助了reactive函数,所以需要监听
.value
或者开启deep,此时依旧无法正确获取oldVal//方式一:
watch(user,(newval,oldval)=>{
console.log('user',newval,oldval)
},{
deep:true
})
//方式二:
watch(user.value,(newval,oldval)=>{
console.log('user',newval,oldval)
})
3.watchEffect函数 作用:监听函数内用到所有属性
watchEffect(()=>{
user.income = user.income1 + user.income2
user.expend = user.expend1 + user.expend2
user.total = user.income - user.expend
console.log('watchEffect user++++',user)
})
watchEffect 有点像 computed:
- computed注重结果,需要写返回值
- watchEffect注重过程,不用写返回值
destroyed(不起作用了) => unmounted
2.composition API形式的生命周期 beforeCreate => setup
created => setup
beforeMount => onBeforeMount
mounted => onMounted
beforeUpdate => onBeforeUpdate
updated => onUpdated
beforeUnmount => onBeforeUnmount
unmounted => onUnmounted
3.composition API 和 生命周期配置 的优先级 尽管开发时,不太可能即用composition API和生命周期配置,但需了解 composition API 比 生命周期配置先触发
4.el vue2时,即使你没有配置el,beforeCreate和created也会触发;
而vue3中,如果你没有配置el,则不会触发beforeCreate和created
八、自定义hook函数 本质是一个函数,把setup函数中使用的composition API进行了封装
类似于vue2中的mixin
优势:复用代码,让setup中的逻辑更清楚易懂
PS:尽量使用
use***
命名,例如usePoint九、toRef 创建一个ref对象,其value值指向另一个响应式对象中的某个属性
const name = toRef(user,'name')
const c = toRef(user.job.a,'c')
可以用来将响应式对象中的某个属性单独提供给外部使用
如果要创建扩展一个响应式对象的所有属性时,可以用toRefs
setup() {
const user = reactive({
name:"henry",
age:25
})
return {
...toRefs(user)
};
}
推荐阅读
- 程序员|你需要知道的有关Selenium异常处理的都在这儿
- 【Python】系列|【Python】面试官:元组列表都分不清,回去等通知pa
- spring|什么是IOC(教你手撸一个IOC容器)
- Python|乱世买黄金(用python分析一下最近的股票市场)
- java基础|JAVA基础之超详细面向对象程序设计一|CSDN创作打卡
- python|学了这么久的Python,到底是什么水平(用这两个项目就能得到检验)
- Python数据可视化|python 数据可视化01
- 数据库|数据库(基础SQL)
- JAVA高并发程序设计|多线程关于无锁的线程是否安全问题