目录
vue3之toRef、toRefs、toRaw
vue3之toRef
- toRef是将对象中的某个值转化为响应式数据 toRef(obj,key)
- 注意点:就是 toRef 修改的值,只能修改原始对象为 响应式对象,否则视图无法变化。
toRef定义原始数据非响应式数据
- toRef 如果原始对象是非响应式的就不会更新视图 数据是会变的
<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 如果原始对象是非响应式的就不会更新视图 数据是会变的
// toRef 如果原始对象是响应式时,原始数据,和copy的数据 都会产生影响,视图也发生变化
const change = () => {
state.value = 3
obj.count = 3
console.log('原始obj', obj)
console.log('引用state', state)
}
</script>
- 原始数据非响应式数据 效果
toRef定义原始数据为响应式数据
- toRef 如果原始对象是响应式时,原始数据,和copy的数据 都会产生影响,视图也发生变化
<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>
- 效果:
vue3之 toRefs 可批量创建响应式数据
- 也就是对对象解构时,解构出来的值为非响应式数据,但使用 toRefs 定义后 这些被解构出来的值 为响应式数据
解构对象方式1
<!-- -->
<template>
<div>
<div>
<div>toRef :name - {{ name }} - age - {{ age }}</div>
<button @click="changeData">修改 数据</button>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, toRef } from 'vue'
type Man = {
name: string
age: number
}
const man = reactive<Man>({
name: 'xzl',
age: 10
})
const toRefs = <T extends object>(object: T) => {
const obj: any = {}
for (let key in object) {
obj[key] = toRef(object, key)
}
return obj
}
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>
解构对象方式2
<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>
- 效果
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包裹之后的对象,永远不能转成响应式数据,即使使用ref包裹。页面不会发生改变
- 注意点:前提不是先使用 reactive 包裹 当前数据转化为 响应式数据了
<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>
- 效果
- 点击时候,name值 不修改
- 点击时候,name值 不修改