Reactive
ref
支持所有类型,reactive
只支持引用类型Array,Object,Map,Set
ref
取值、赋值都需要.value
,而reactive
不需要- 因为
reactive
是一个proxy
代理对象,直接赋值会对proxy
代理对象进行覆盖,所以不能直接赋值- 解决方法一:数组使用
push
和 解构(解构不会丢失响应式) - 解决方法二:添加一个对象,把需要赋值的元素作为一个属性去处理
- 解决方法三:使用
Object.assign
去整体替换
- 解决方法一:数组使用
<template>
<div>
<!-- 表单 -->
<!-- <form>
<input v-model="form.name" type="text">
<br>
<input v-model="form.age" type="text">
<br>
<button @click.prevent="submit">submit</button>
</form> -->
<!-- 数组 -->
<ul>
<li v-for="item in list.arr">{{ item }}</li>
</ul>
<button @click.prevent="add">add</button>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
//表单
// let form = reactive ({
// name: 'vuee',
// age: 24
// })
// form.age = 25
//数组
// let list = reactive<string[]>([])
// 解决方法二
let list = reactive<{
arr: string[]
}>({
arr: []
})
const add = () => {
// list.push('JDG')
//异步获取数组
setTimeout(() => {
let res = ['EDG', 'RNG', 'JDG']
// 异步获取数组,不能直接赋值(赋值会成功,但是不会在页面渲染)
list.arr = res
// 解决方法一
// list.push(...res)
console.log(list);
}, 2000);
}
</script>
<style lang="scss" scoped></style>
Proxy代理对象:Proxy是JavaScript中的一个内置对象,允许你创建一个代理对象来包装另一个对象,它们引用的是同一个原始对象(地址相同)。并且可以在代理对象上设置各种拦截器,以便捕获对原始对象的访问和操作。
如果直接将一个新的值赋给代理对象,这将覆盖代理对象原来的值。这样做会破坏原有的响应式性质,因为代理对象的拦截器不会捕获直接赋值操作。
reactive
是深层的,当里面有对象等(除了基础类型)都会继续代理。
如果将 reactive
对象里面的数据进行解构,解构后的引用类型仍然具有响应式,而解构后的变量不再具有响应式。如果希望得到响应式的变量,可以使用 toRef
获取数据。
readonly
<template>
<div>
<button @click="show">show</button>
</div>
</template>
<script setup lang="ts">
import { reactive, readonly } from 'vue';
let obj = reactive({ name: 'xiaohu' })
const read = readonly(obj)
const show = () => {
// read.name = 'dahu' 只读,不能修改
obj.name = 'dahu'
// obj可以修改
console.log(obj);
}
</script>
<style lang="scss" scoped></style>
shallowReactive
shallowReactive
也会被reactive
影响,和 ref
同理
<template>
<div>
{{ obj }}
<button @click="edit">edit</button>
</div>
</template>
<script setup lang="ts">
import { shallowReactive } from 'vue';
let obj: any = shallowReactive({
foo: {
bar: {
num: {
name: 1
}
}
}
})
const edit = () => {
// obj.foo.bar.num.name = 2
// 只能对foo层进行更改
obj.foo = {
name: 2
}
console.log(obj);
}
</script>
<style lang="scss" scoped></style>