文章目录
-
- 回顾Vue2响应式
- Vue3实现响应式
- Ref
- Reactive函数
- 对比reactive和ref
- Vue3组件中的模板结构可以没有根标签div
- 组合式API
- Setup注意点
- 计算属性与监听computed
- Watch
- WatchEffect
- 父组件传值给子组件
- 父组件调用子组件方法
- 子组件调父组件方法
- Vue3生命周期
- 自定义hook函数
- toRef
- 其他组合API
- shallowReactive
- shallowRef
- readonly和shallowOnly
- ToRaw和markRow
- customRef
- Provide和inject
- 响应式数据的判断
- Composition API的优势
- 新的组件
- Fragment
- Teleport
- Suspense
- Vue3其他变化
回顾Vue2响应式
vue2响应式存在的问题:
对象新增属性,删除属性,不会实时响应到界面中。
数组直接通过下标进行修改,不会实时响应到界面中。
vue2中将响应式的数据放到data中,换句话中,只有data中的数据才是响应的。
<script>
export default {
data() {
return {
person: {
name: '张三',
age: 18,
hobby: ['学习', '吃饭']
}
}
},
methods: {
editAddSex() {
// 修改对象中属性用this.$set或者Vue.$set
this.$set(this.person, 'sex', '女')
},
deleteName() {
// 删除对象中属性用this.$delete或者Vue.$delete
this.$delete(this.person, 'name')
},
updateHobby() {
// 修改数组用this.$set或者splice
this.person.hobby.splice(0,1,'逛街')
}
}
}
</script>
Vue2使用object.defineProperty来劫持数据是否发生改变,如下:
<script>
let person = {
name:'风冷螺杆',
type:'三联供'
}
let p={
}
Object.defineProperty(p,'name',{
configurable:true,
get(){
console.1og('有人读取了name')
return person.name
}
set(value){
console.1og('有人修改了name')
person.name = value
}
Object.defineProperty(p,'age',{
configurable:true,
get(){
console.log('有人读取了age')
return person.age
}
set(value){
console.1og('有人修改了age')
person.age = value
}
</script>
能监测到获取和修改属性:
新增的属性没有get和set:
删除name属性:
综上,获取和修改一个属性可以捕获到,但是新增和删除属性是捕获不到的,所以使用 s e t 和 set和 set和delete方法才能响应。
Vue3实现响应式
- 如下代码,p = new Proxy()后,p是一个proxy对象,是person的一个代理对象,对p的修改会映射到person身上:
let person = {
name: '风冷螺杆',
type: '三联供'
}
let p= new Proxy(person, {
})
上面代码只是说P是person的代理对象,p改变,person跟着改变,但是并没有做到响应式,也就是变化并没有捕获到。
2) Vue3捕获响应:
结果如下:对对象的增删改查全部捕获到,并且映射到person中。
其中set方法,既捕获新增又捕获修改。
3) 对上面代码进行优化,vue3中是使用Reflect来对数据进行修改。
综上,实现原理: 通过proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等。
通过Reflect(反射):对被代理对象(原对象)的属性进行操作。
Ref
RefImpl:引用对象,如果想让一个普通变量变成响应式的,就需要把这个变量丢给ref。
<template>
<h1>设备名称:{
{
name }}</h1>
<h1>寿命:{
{
age }}</h1>
<button @click="sayHello">点击</button>
</template>
<script>
import {
ref } from 'vue'
export default {
name: 'App',
setup() {
// 数据
let name = ref('风冷模块')
let age = ref(