一、ref
利用ref将一个对象中的属性变成响应式的数据,ref是对原始数据的拷贝,修改响应式的数据不会影响到原始数据,但会触发页面更新。
let obj = { name: "zs" };
let state = ref(obj.name);
二、toRef
将对象中的某个值转化为响应式数据 toRef(obj,key),toRef创建的数据的视图更新是需要追根溯源的。
原始数据为非响应式数据 -> 不会触发视图更新
原始数据为响应式数据 -> 会触发视图更新
1、原始数据为非响应式数据
<template>
<div>
<button @click="change">change</button>
<div>{{ obj }}</div>
</div>
</template>
<script setup lang="ts">
import { toRef, reactive } from 'vue'
const obj = {
num: 1,
count: 2,
}
let state = toRef(obj, 'num')
// toRef 如果原始对象是非响应式的就不会更新视图 数据是会变的
const change = () => {
state.value = 3
obj.count = 3
console.log('原始obj', obj)
console.log('引用state', state)
}
</script>
2、原始数据为响应式数据
<template>
<div>
<button @click="change">change</button>
<div>{{ obj }}</div>
</div>
</template>
<script setup lang="ts">
import { toRef, reactive } from 'vue'
const obj = reactive({
num: 1,
})
let state = toRef(obj, 'num')
// toRef 对原始数据,和copy的数据 都会产生影响 若是使用reactive定义的复杂数据,也是会联动视图
const change = () => {
state.value = 3
console.log('原始obj', obj)
console.log('引用state', state)
}
</script>
三、toRefs
toRefs 可批量创建响应式数据,当我们解构对象时,解构出来的值为非响应式数据,但使用 toRefs 定义后 这些被解构出来的值为响应式数据。
1、解构对象方式1
<template>
<div>
<button @click="change">change</button>
<div>{{ obj }}</div>
</div>
</template>
<script setup lang="ts">
import { toRefs, reactive } from 'vue'
const obj = reactive({
num: 1,
count: 2,
})
let { num, count } = obj // 直接解构出来的数据,是非响应式的数据
console.log('num', num, 'count', count)
let { num: num1, count: count1 } = toRefs(obj) // 通过toRefs定义为响应式数据
console.log('num1', num1, 'count1', count1)
const change = () => {
num = 10
count1.value = 100
console.log('事件num', num)
}
</script>
2、解构对象方式2
<template>
<div>
<div>
<div>toRef :name - {{ name }} - age - {{ age }}</div>
<button @click="changeData">修改数据</button>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
const man = reactive({
name: 'xzl',
age: 10
})
const { name, age } = toRefs(man)
console.log(' name,age', name.value, age.value) // 输出修改前的数据
const changeData = () => {
name.value = 'XZL'
age.value = 100
console.log(' name,age2', name.value, age.value) // 输出修改后的数据
}
</script>
四、toRaw
toRaw将响应式对象转化为普通对象,数据变化,视图不变化
<template>
<div>
<button @click="change">change</button>
<div>{{ obj }}</div>
</div>
</template>
<script setup lang="ts">
import { toRaw, reactive } from 'vue'
const obj = reactive({
num: 1,
count: 2,
})
let newObj = toRaw(obj)
console.log('newObj', newObj)
const change = () => {
newObj.count = 33
console.log('newObj2', newObj)
}
</script>
五、markRaw
markRaw标记一个对象,使其永远不会再成为响应式对象。
应用场景:
- 个别属性不需要响应式
- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能
<template>
<div class="main">
<button @click="changeState">修改state</button>
我是state -- {{ state }} <br />
</div>
</template>
<script setup lang="ts">
import { reactive, ref, markRaw } from 'vue'
let obj = {
name: 'ppp',
} //原始数据
//设置 obj 这个数据 不被追踪
obj = markRaw(obj)
let state = reactive(obj)
const changeState = () => {
state.name = 'oo'
}
</script>