什么是解构
将一个对象中的属性解析出业务需要的变量。在实际业务开发中非常实用。
解构
数组解构
let input = [1, 2];
let [first, second] = input;
console.log(first); // outputs 1
console.log(second); // outputs 2
//解构作用于已声明的变量会更好
// swap variables
[first, second] = [second, first];
对象解构
let o = {
a: "foo",
b: 12,
c: "bar"
};
let { a, b } = o;
这通过 o.a
and o.b
创建了 a
和 b
。 注意,如果你不需要 c
你可以忽略它。
如果将解构出来变量响应式化
toRef
toRef返回的值是否具有响应性取决于被解构的对象本身是否具有响应性。
响应式数据经过toRef返回的值仍具有响应性
非响应式数据经过toRef返回的值仍没有响应性。
<template>
<div>
<button @click="change">按钮</button><br>
{{state}}
</div>
</template>
<script setup lang="ts">
import { reactive, toRef } from 'vue'
const obj = reactive({
name: '树哥',
age: 18
})
const state = toRef(obj, 'age')
const change = () => {
state.value++
console.log('obj:', obj, 'state:', state);
}
</script>
<style>
.input-with-select .el-input-group__prepend {
background-color: var(--el-fill-color-blank);
}
</style>
//这个对响应式对象进行解构, change函数触发,视图的数据也发生变化.
<template>
<div>
<button @click="change">按钮</button><br>
{{state}}
</div>
</template>
<script setup lang="ts">
import { reactive, toRef } from 'vue'
const obj = {
name: '树哥',
age: 18
}
const state = toRef(obj, 'age')
const change = () => {
state.value++
console.log('obj:', obj, 'state:', state);
}
</script>
<style>
.input-with-select .el-input-group__prepend {
background-color: var(--el-fill-color-blank);
}
</style>
//toRef作用于非响应式变量。页面的视图数据也没有发生变化。
toRefs
toRefs相当于对对象内每个属性调用toRef,toRefs返回的对象内的属性使用时需要加.value,主要是方便我们解构使用。
<template>
<div>
<button @click="change">按钮</button>
name--{{name}}---age{{age}}
</div>
</template>
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
const obj = reactive({
name: '树哥',
age: 18
})
let { name, age } = toRefs(obj)
const change = () => {
age.value++
name.value = '张麻子'
console.log('obj:', obj);
console.log('name:', name);
console.log('age:', age);
}
</script>
在解构 Vue 的props时,prop数据在过程中会失去反应性。然而,有一种方法可以在解构props时保持反应性。你可以使用toRefs指令来包装props对象,并在解构过程中保持反应性。有了这个指令,你可以在不担心失去反应性的情况下解构prop数据。
<script setup lang="ts">
import { toRefs } from 'vue'
const props = withDefaults(
defineProps<{
event: object;
address: string;
}>(),
{}
);
const { address } = toRefs(props)
</script>
<template>
<div class="font-medium bg-gray-100 text-gray-700 py-3 px-3 rounded">
{{ address }}
</div>
</template>
storeToRefs
直接结构store实例会 使数据丢失响应式
通过storeToRefs包裹 store实例可以解决这一问题
storeToRefs只能把state里面的数据变为单独的响应式 的 ref 但是不能结构 actions中的方法
<template>
<div>
<button @click="change">按钮</button><br>
{{ language }}
</div>
</template>
<script setup lang="ts">
import { reactive, toRef } from 'vue'
import {storeToRefs} from "pinia"
import { langStore } from "@/store/i18n"
// 可以获得language相关信息, 却无法支持响应化
// const { language } = langStore();
// 可以获得language相关信息, 支持响应化
const { language } = storeToRefs(langStore());
console.log("---language--" + language);
const change = ()=>{
language.value = "en"
console.log("--log--");
}
</script>
<style>
</style>
如何将对象去除响应式化
toRaw
将响应式对象修改为普通对象
<template>
<div>
<button @click="change">按钮</button>
{{data}}
</div>
</template>
<script setup lang="ts">
import { reactive, toRaw } from 'vue'
const obj = reactive({
name: '树哥',
age: 18
})
const data = toRaw(obj)
const change = () => {
data.age = 19
console.log('obj:', obj, 'data:', data);
}
</script>
unref
Vue3 unref是一个调用ref对象时返回ref.value的函数,它当参数类型为ref时,返回ref.value,否则返回参数本身.
import { ref, reactive } from 'vue'
const a = ref(1)
const b = ref('string')
const c = reactive({
name: 'kevin',
age: 22
})
console.log(unref(a), unref(b), unref(c)) // 1, 'string', { name: 'kevin', age: 22 }
console.log(unref(a) === a.value) // true
console.log(unref(b) === b.value) // true
console.log(unref(c) === c) // true
在上面的代码中,我们通过unref函数获取了ref对象所关联的值。我们可以看到,当参数类型为ref时,unref函数返回ref.value,否则返回参数本身。通过unref函数,我们可以轻松获取ref对象所关联的值。