理解:
1.ref是定义简单类型和单一对象
2.reactive是用来定义复杂的类型
响应式编程
在Vue中,响应式编程是一种使数据与UI页面保持同步的方式。当数据变化时,UI会自动更新,反之亦然。这种机制大大简化了前端开发,不必手动处理DOM更新。
Ref()
ref接受一个内部值,返回一个响应式的、可更改的ref对象,此对象只有一个只想其内部值的属性
详细信息
res对象是可更改的,就是说你可以为
如果将一个对象赋值给了ref,那么这个对象将通过
实例
import { ref } from 'vue'; const count = ref(0); // 访问数据 console.log(count.value) // 输出 0 // 更新数据 count.value = 1; console.log(count.value) // 输出1
为什么要使用Ref
当你在模板中使用了一个ref,然后改变了这个ref的值时,Vue就会自动检测到这个变化,并且相应地更新DOM。这是通过一个基于依赖追踪的响应式系统实现的。当一个组件首次渲染时,Vue会追踪在渲染过程中使用的每一个ref。然后,当一个ref被修改时,它会触发追踪它的组件的一次重新渲染。
另一个ref的好处时,与普通变量不同,你可以将ref传递给函数,同事保留对最新值和响应式连接的访问。当将复杂的逻辑重构为可重用的代码时,这将非常有用。
优势
1.明确的数据访问语法(.value)
2.适用于包装基本数据类型,如数字、字符串等。
3.更容易阅读和理解,适合处理简单的响应式数据。
Reactive()
返回一个对象的响应式代理。可以用于创建响应式对象,而不仅仅时基本数据类型。优势主要在于处理复杂数据结构时更加灵活,能够包装整个对象。
详细信息
响应式转换是“深层”的:它会影响到所有嵌套的属性。一个响应式对象也将深层地解包任何
实例
import { reactive } from 'vue'; const user = reactive({ name: 'John', age: 30, }); // 访问数据 console.log(user.name); // 输出 'John' // 更新数据 user.age = 31; console.log(user.age) // 输出 31
ref的解包
const count = ref(1) const obj = reactive({ count }) // ref 会被解包 console.log(obj.count === count.value) // true // 会更新 `obj.count` count.value++ console.log(count.value) // 2 console.log(obj.count) // 2 // 也会更新 `count` ref obj.count++ console.log(obj.count) // 3 console.log(count.value) // 3
1.有限的值类型:它只能用于对象类型(对象、数组和如
2.不能替换整个对象:由于Vue的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:
let state = reactive({ count: 0 }) // 上面的 ({ count: 0 }) 引用将不再被追踪 // (响应性连接已丢失!) state = reactive({ count: 1 })
3.对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:
const state = reactive({ count: 0 }) // 当解构时,count 已经与 state.count 断开连接 let { count } = state // 不会影响原始的 state count++ // 该函数接收到的是一个普通的数字 // 并且无法追踪 state.count 的变化 // 我们必须传入整个对象以保持响应性 callSomeFunction(state.count)
优势
1.适用于包装复杂的对象和数据结构,包括嵌套对象。
2.不需要额外的语法(
3.更适合处理多个相关属性的情况,如表单字段或组件状态。
Ref与Reactive的区别
1.数据类型:
2.访问数据:使用
3.数据的包装:
Vue3响应式系统的原理
Vue3的响应式系统是基于JavaScript ES6中新增的
创建一个Proxy对象
创建一个
const target = { name: 'John' }; const handler = { get(target, key) { console.log(`Getting ${key} property`); return target[key]; }, set(target, key, value) { console.log(`Setting ${key} property to ${value}`); target[key] = value; } }; const proxy = new Proxy(target, handler); console.log(proxy.name) // 会触发 get 拦截器 输出“Getter name property” "John" proxy.age = 30 // 会触发 set 拦截器,输出 “Setter age property to 30”
在上面的代码中,我们创建了一个