概述
reactive 用来返回一个对象的响应式代理
语法:
function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
使用:
基本使用:
具体步骤如下:
- 使用
Vue.reactive, 接收一个对象并生成一个响应式对象 - 从
setup()函数中返回出去 - 在模板中使用
响应式对象.xxx进行挂载访问
<script>
import { defineComponent, reactive } from 'vue';
export default defineComponent({
name: 'Comp',
setup(props, ctx) {
const state = reactive({
name: 'zhangsan',
age: 18,
career: 'programmer'
});
return {
state
};
}
});
</script>
<template>
<div class="wrapper">
<p>
Name: {{ state.name }}
</p>
<p>
Age: {{ state.age }}
</p>
<p>
Career: {{ state.career }}
</p>
</div>
</template>
注意
- reactive 对象的所有值都是深度代理的,不需要担心深层数据变化而视图没有响应的问题。
- reactive 对象中的值不能够直接解构,这样会丧失原有的【响应性】!!!
配合其他组合式 API 使用
有时候,使用 state.xxx会比较麻烦,而直接解构会丧失响应式!
在 Vue 里面提供了其他的组合式 API 可以将 state 中所有的字面量转化成响应式数据并提供给视图使用:
- 配合
toRef使用:
<script>
import { defineComponent, reactive, toRef } from 'vue';
export default defineComponent({
name: 'Comp',
setup(props, ctx) {
const state = reactive({
name: 'zhangsan',
age: 18,
career: 'programmer'
});
const name = toRef(state, 'name'),
age = toRef(state, 'age'),
career = toRef(state, 'career');
return {
name,
age,
career,
};
}
});
</script>
<template>
<div class="wrapper">
<p>
Name: {{ name }}
</p>
<p>
Age: {{ age }}
</p>
<p>
Career: {{ career }}
</p>
</div>
</template>
- 配合
toRefs使用:
<script>
import { defineComponent, reactive, toRefs } from 'vue';
export default defineComponent({
name: 'Comp',
setup(props, ctx) {
const state = reactive({
name: 'zhangsan',
age: 18,
career: 'programmer'
});
return {
...toRefs(state)
};
}
});
</script>
<template>
<div class="wrapper">
<p>
Name: {{ name }}
</p>
<p>
Age: {{ age }}
</p>
<p>
Career: {{ career }}
</p>
</div>
</template>
- 配合
computed使用
<script>
import { defineComponent, reactive, computed } from 'vue';
export default defineComponent({
name: 'Comp',
setup(props, ctx) {
const state = reactive({
name: 'zhangsan',
age: 18,
career: 'programmer'
});
const name = computed(() => state.name),
age = computed(() => state.age),
career = computed(() => state.career);
return {
name,
age,
career,
};
}
});
</script>
<template>
<div class="wrapper">
<p>
Name: {{ name }}
</p>
<p>
Age: {{ age }}
</p>
<p>
Career: {{ career }}
</p>
</div>
</template>
总结:
reactive响应式转换是“深层”的:它会影响到所有嵌套的属性。- 如果
reactive中还有其他的响应式对象(比如ref、readonly),reactive也会去维持它们的【响应性】。 - 当访问到某个响应式数组或 Map (Set, WeakMap, WeakSet)这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包。(proxyObject.map.mapKey.value);
- 若要避免深层响应式转换,只想保留对这个对象顶层次访问的响应性,请使用
shallowReactive()作替代。 - 不要直接操作原始对象 (raw object)!为了保证视图的正确更新,应该对 reactive 对象进行操作
- 使用
reactive包裹ref对象,reactive和ref对应的变量具有相同的引用 - 将一个
ref赋值给为一个reactive属性时,该ref会被自动解包