很激动进入了 Vue 3 的学习,作为一个已经上线了三年多的框架,很多项目都开始使用 Vue 3 来编写了
这一组文章主要聚焦于 Vue 3 的新技术和新特性
如果想要学习基础的 Vue 语法可以看我专栏中的其他博客
Vue(一):Vue 入门与 Vue 指令
Vue(二):计算属性与 watch 监听器
Vue(三):Vue 生命周期与工程化开发
一篇文章快速通关 Vuex(适合小白学习)
Vue 框架前导:详解 Ajax
快速打通 Vue 3(一):基本介绍与组合式 API
上一篇 Vue3 博客:快速打通 Vue 3(一):基本介绍与组合式 API
后续还会继续更新,期待大家的关注!
04. 响应式数据 —— ref 与 reactive
4.1 ref 创建响应式数据
要点概览:
- 要使用需要加入
.value
- 模板会自动添加
通过上面的尝试我们知道,在 setup
中声明的数据默认 不是响应式的,我们需要手动将其声明为响应式,这里就需要 ref
函数。
语法 let xxx = ref(初始值)
,返回值是一个 RefImpl
的实例 对象
对象中的 value
属性 是响应式的,相当于 ref
为我们的数据上了一层包装,数据放在其中的 value
属性上,我们操控数据要通过操控其 value
属性来实现
这意味着我们只写 sum += 1
是无法实现我们想要的效果的
模板会自动为我们添加 value
属性,模板中直接写 {{数据名}}
即可
<template>
<div class="person">
<h2>当前数字的为 {{ sum }}</h2>
<button @click="addOne">+1</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let sum = ref(0);
function addOne() {
console.log(sum);
sum.value += 1;
}
</script>
我们来打印一下整个对象
4.2 reactive 创建对象类型的响应式数据
要点概览
reactive
函数只能创建响应式对象数据- 创建的响应式数据是深层次1的
- 修改对象为新对象会破坏其响应式特性
响应式数据除了基本的数据类型还包括对象类型,上面的 ref
函数也可以创建对象类型的响应式数据
但是要借助 reactive
函数实现,所以我们这里先来说一下 reactive
函数
reactive
函数 只能 创建对象类型的响应式数据
语法:let xxx = reactive(源对象)
返回值是一个 Proxy
的实例对象,简称响应式对象
<template>
<div class="person">
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<button @click="changeName">changeName</button>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
let person = reactive({
name: 'Tom',
age: '18'
})
function changeName () {
person.name = 'Jack';
}
</script>
且 reactive
声明的对象是 深层次 的
<template>
<div class="person">
<h2>数字:{{a.b.c}}</h2>
<button @click="change">change</button>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
let a = reactive({
b: {
c: 111
}
})
function change () {
a.b.c = 1;
}
</script>
上面声明了一个嵌套对象,我们来尝试修改嵌套对象中的数据。
需要注意的是,我们不能修改对象,reactive
是将原本地址上的对象变为响应式对象。
但如果我们创建一个新的对象并且赋值给它,就不是响应式的了(用的不多但需要了解)。
官方文档:
值得注意的是,
reactive()
返回的是一个原始对象的 Proxy,它和原始对象是不相等的。只有代理对象是响应式的,更改原始对象不会触发更新。因此,使用 Vue 的响应式系统的最佳实践是 仅使用你声明对象的代理版本。
function changePerson() {
person = {name: 'Jack', age: 10};
}
比如我们尝试修改,界面是没有任何变化的
4.3 ref 声明对象类型的响应式数据
要点概览:
ref
的响应式对象是借助reactive
函数创建的- 使用响应式对象仍然需要
.value
上面我们提到 ref
函数也可以创建对象类型的响应式数据,让我们来尝试一下:
<template>
<div class="person">
<h2>姓名{{person.name}}</h2>
<h2>年龄{{person.age}}</h2>
<button @click="changeAge">changeAge</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let person = ref({
name: 'Tom',
age: 18
})
function changeAge() {
console.log(person);
person.value.age++;
}
</script>
还是经典的修改年龄的界面,我们打印出来创建的这个 person
对象
非常熟悉的内容,正是我们上面 reactive
函数创建的响应式对象
我们使用 ref
创建的对象仍然需要加上 .value
4.4 ref 与 reactive
要点概述:
- 推荐使用
ref
作为主要 APIreactive
在某些特定情况可以使用
根据官方文档,reactive
有如下的缺点:
所以一般推荐使用 ref
作为主要的 API
但是当我们的对象深度很深的时候,例如表单对象,我们可能要写无数个 value
比较影响代码的美观,这时候在不影响的情况下是可以使用 reactive
的。
补充:关于解构
在Vue中,解构操作通常用于从对象或数组中提取数据,并将其赋值给变量,以便在Vue组件中使用。Vue支持解构赋值语法,让开发者可以更方便地操作组件中的数据。
- 对象解构
在Vue组件中,可以使用对象解构从组件的数据对象中提取数据。例如:
javascriptCopy codeexport default {
data() {
return {
person: {
name: 'Alice',
age: 30,
city: 'New York'
}
};
},
mounted() {
const { name, age, city } = this.person;
console.log(name); // 输出:Alice
console.log(age); // 输出:30
console.log(city); // 输出:New York
}
};
- 数组解构
数组解构可以用于解构数组中的数据。例如:
javascriptCopy codeexport default {
data() {
return {
numbers: [1, 2, 3, 4, 5]
};
},
mounted() {
const [first, second, third] = this.numbers;
console.log(first); // 输出:1
console.log(second); // 输出:2
console.log(third); // 输出:3
}
};
- 在模板中使用解构
还可以在Vue的模板中使用对象解构,例如:
htmlCopy code<template>
<div>
<p>{{ person.name }}</p>
<p>{{ person.age }}</p>
<p>{{ person.city }}</p>
</div>
</template>
<script>
export default {
data() {
return {
person: {
name: 'Alice',
age: 30,
city: 'New York'
}
};
}
};
</script>
在模板中,可以直接通过{{ 变量名 }}
的方式使用解构后的数据。
4.5 toRefs 与 toRef
要点概览:
- 响应式对象的属性转换为
ref
对象toRefs
批量转化呢,toRef
实现单个转换- 需要加
.value
操控
我们来尝试将对象解构,将其中的属性交给模板 <template>
去显示
<template>
<div class="person">
<h2>姓名{{name}}</h2>
<h2>年龄{{age}}</h2>
<button @click="changeAge">changeAge</button>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
let person = reactive({
name: 'Tom',
age: 18
})
let {name, age} = person;
function changeAge() {
console.log(person);
age.value++;
}
</script>
那这个属性是响应式的吗?
很明显不是,无法将改变的属性显示在网页上,那应该怎么将结构出来的属性变为响应式的呢?
就需要这里讲的 toRefs
语法 let {name, age} = toRefs(person);
这样数据就变为响应式的了
toRef
与 toRefs
作用相同,但可以指定需要将哪个属性变为响应式的
语法:let name = toRef(person, 'name')
这样就可以将响应式对象中的属性也设置为响应式的
转换出来的是 ref
对象,很明显操控需要加 .value
补充——插件自动填充 .value
我们有时候会忘记添加 .value
或者会加错,这是和可以借助插件来自动为我们添加 .value
这里用到的插件是我们之前提到的 Vue Language Features (Volar)
打开设置界面 -> 拓展 -> Volar -> 打开 Auto Insert: Dot Value
深层次即对象内嵌套的对象也会被声明为响应式的对象。 ↩︎