Reactive全家桶
reactive
用来定义复杂的数据类型:对象、数组
reactive 源码约束了我们的类型,ref支持所有类型
绑定普通的数据类型是不被允许的 会报错
绑定普通数据类型用 ref,你如果用 ref 去绑定 对象 或者 数组 等复杂的数据类型 你去看源码里面其实也是 去调用 reactive,使用 reactive 去修改值无须 .value
<template>
<div>
<p>{{rea}}</p>
<input type="text" v-model="rea.name">
<hr>
<input type="text" v-model="rea.age">
</div>
</template>
<script setup lang="ts">
import { ref,reactive} from 'vue'
//ref支持所有类型 reactive 复杂的数据类型
let rea=reactive({
name:"zs",
age:23
})
//reactive 修改值不需要 .value
rea.age=18
</script>
<style>
</style>
数据异步赋值问题
这样直接赋值页面是不会变化的因为会脱离响应式
<template>
<div>
<ul>
<li v-for="item in list" :key="item">{{item}}</li>
</ul>
<button @click="add">add</button>
</div>
</template>
<script setup lang="ts">
import { ref,reactive} from 'vue'
let list=reactive([])
const add=()=>{
setTimeout(()=>{
let res=['1','2','3']
list=res;//不能直接赋值,会破坏响应式对象
console.log(list);
},1000)
}
</script>
<style>
</style>
解决方案push
<template>
<div>
<ul>
<li v-for="item in list" :key="item">{{item}}</li>
</ul>
<button @click="add">add</button>
</div>
</template>
<script setup lang="ts">
import { ref,reactive} from 'vue'
let list=reactive([])
const add=()=>{
setTimeout(()=>{
let res=['1','2','3']
list.push(...res)//解决方案 push
console.log(list);
},1000)
}
</script>
<style>
</style>
解决方案-解构、包裹一层对象
<template>
<div>
<ul>
<li v-for="item in list.arr" :key="item">{{item}}</li>
</ul>
<button @click="add">add</button>
</div>
</template>
<script setup lang="ts">
import { ref,reactive} from 'vue'
let list=reactive({//包裹一层对象
arr:[]
})
const add=()=>{
setTimeout(()=>{
let res=['1','2','3']
list.arr=res
console.log(list);
},1000)
}
</script>
<style>
</style>
readonly
拷贝一份proxy对象将其设置为只读
受原始对象影响
<template>
<div>
<button @click="show">show</button>
</div>
</template>
<script setup lang="ts">
import { ref,reactive,readonly} from 'vue'
let obj=reactive({
name:'原始对象'
})
const read=readonly(obj)
const show=()=>{
//obj.name='修改后'
read.name='read修改'
console.log(obj,read);
}
</script>
<style>
</style>
shallowReactive
只能对浅层的数据,如果是深层的数据只会改变值,不会改变视图
浅响应式
只处理对象最外层属性的响应式
<template>
<div>
<p>shallowReactive:{{obj.foo.bar.num}}</p>
<button @click="edit">add</button>
</div>
</template>
<script setup lang="ts">
import { ref,reactive,readonly,shallowReactive} from 'vue'
let obj=shallowReactive({
foo:{
bar:{
num:1
}
}
})
const edit=()=>{
obj.foo.bar.num+=1
console.log(obj.foo.bar.num)//后台变,视图不变
}
</script>
<style>
</style>
只能处理第一层的属性,如下,
第一层被改变后其他层也会变化(视图和后台都变化)
只触发第三层、第二层只有后台会变
<template>
<div>
<p>第三层:{{obj.foo.bar.num}}</p>
<button @click="edit3">add</button>
<hr>
<p>foo.name:{{obj.foo.name}}</p>
<button @click="edit2">add</button>
<hr>
<p>第一层:{{obj.str}}</p>
<button @click="edit1">add</button>
</div>
</template>
<script setup lang="ts">
import { ref,reactive,readonly,shallowReactive} from 'vue'
let obj=shallowReactive({
str:"第一层",
foo:{
name:"第二层",
bar:{
num:1
}
}
})
const edit3=()=>{
obj.foo.bar.num+=1
console.log(obj.foo.bar.num)
}
const edit2=()=>{
obj.foo.name="修改后"
console.log(obj.foo.name);
}
const edit1=()=>{
obj.str="第一层被修改"
console.log(obj.str);
}
</script>
<style>
</style>
shallowReactive被reactive影响
<template>
<div>
<p>shallowReactive:{{obj.foo.bar.num}}</p>
<p>reactive:{{obj1.name}}</p>
<button @click="edit">add</button>
</div>
</template>
<script setup lang="ts">
import { ref,reactive,readonly,shallowReactive} from 'vue'
let obj1=reactive({name:"zs"})
let obj=shallowReactive({
foo:{
bar:{
num:1
}
}
})
const edit=()=>{
obj.foo.bar.num+=1
console.log(obj.foo.bar.num)
console.log("----------------");
obj1.name="change"
console.log(obj1.name);
}
</script>
<style>
</style>
都变化了