【Vue3】响应式数据
- 背景
- 简介
- 开发环境
- 基本数据类型
- 对象数据类型
- 使用 reactive 定义对象类型响应式数据
- 使用 ref 定义对象类型响应式数据
- ref 和 reactive 的对比
- 使用原则建议
背景
随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。
简介
本文介绍 Vue3 中响应式数据的编写方法。
开发环境
分类 | 名称 | 版本 |
---|---|---|
操作系统 | Windows | Windows 11 |
IDE | Visual Studio Code | 1.91.1 |
基本数据类型
在 【Vue3】组合式 API 基础上修改 Vue 根组件 App.vue 代码。
<!-- 组件结构 -->
<template><div class="person"><h3>姓名:{{ name }}</h3><h3>生日:{{ birth.getFullYear() + '-' + (birth.getMonth() + 1) + "-" + birth.getDate() }}</h3><button @click="showContact">查看联系方式</button><button @click="changeName">修改名字</button></div>
</template><script setup lang="ts" name="App">
import { ref } from 'vue'// 数据定义
let name = ref('哈利·波特')
let birth = new Date('1980-07-31')
let contact = '霍格沃茨魔法学校格兰芬多学院'// 方法定义
function showContact() {alert(contact)
}function changeName() {name.value = 'Harry Potter'
}
</script><!-- 组件样式 -->
<style lang="scss">
.person {background-color: cadetblue;border-radius: 5px;color: white;padding: 20px;button {background-color: gold;border-radius: 5px;padding: 5px 10px;margin-right: 10px;}
}
</style>
对象数据类型
使用 reactive 定义对象类型响应式数据
<!-- 组件结构 -->
<template><div class="person"><h3>姓名:{{ person.name }}</h3><h3>生日:{{ person.birth.getFullYear() + '-' + (person.birth.getMonth() + 1) + "-" + person.birth.getDate() }}</h3><button @click="showContact">查看联系方式</button><button @click="changeName">修改名字</button></div>
</template><script setup lang="ts" name="App">
import { reactive } from 'vue'let person = reactive({name: '哈利·波特',birth: new Date('1980-07-31'),contact: '霍格沃茨魔法学校格兰芬多学院'
})// 方法定义
function showContact() {alert(person.contact)
}function changeName() {person.name = 'Harry Potter'
}
</script><!-- 组件样式 -->
<style lang="scss">
.person {background-color: cadetblue;border-radius: 5px;color: white;padding: 20px;button {background-color: gold;border-radius: 5px;padding: 5px 10px;margin-right: 10px;}
}
</style>
使用 ref 定义对象类型响应式数据
<!-- 组件结构 -->
<template><div class="person"><h3>姓名:{{ person.name }}</h3><h3>生日:{{ person.birth.getFullYear() + '-' + (person.birth.getMonth() + 1) + "-" + person.birth.getDate() }}</h3><button @click="showContact">查看联系方式</button><button @click="changeName">修改名字</button></div>
</template><script setup lang="ts" name="App">
import { ref } from 'vue'let person = ref({name: '哈利·波特',birth: new Date('1980-07-31'),contact: '霍格沃茨魔法学校格兰芬多学院'
})// 方法定义
function showContact() {alert(person.value.contact)
}function changeName() {person.value.name = 'Harry Potter'
}
</script><!-- 组件样式 -->
<style lang="scss">
.person {background-color: cadetblue;border-radius: 5px;color: white;padding: 20px;button {background-color: gold;border-radius: 5px;padding: 5px 10px;margin-right: 10px;}
}
</style>
ref 和 reactive 的对比
ref
可以定义基本类型以及对象类型的响应式数据,而reactive
只能定义对象类型的响应式数据;ref
定义对象类型响应式数据时,底层实际使用的也是reactive
;- 在
<script>
中使用ref
定义的响应式数据时,必须使用变量的.value
属性,reactive
不存在此问题; - 如果为
reactive
定义的响应式数据重新分配一个对象,则会失去响应式行为,可以通过Object.assign()
将reactive
定义的响应式数据对象整体替换掉。 - 通过
console.log
打印出由ref
和reactive
定义的响应式数据,可见其底层实现不同:-
reactive
定义的响应式数据是 JavaScript 标准内置对象Proxy
,是对原对象的代理,可实现对原对象操作的拦截及自定义。
-
ref
定义的响应式数据是RefImpl
的一个实例对象,原数据在value
属性中,可见如果原数据为对象类型,则RefImpl
实例的value
属性也是 JavaScript 标准内置对象Proxy
,底层与reactive
一致。
-
使用原则建议
- 如果需要一个基本类型的响应式数据,则必须使用
ref
; - 如果需要一个对象类型的响应式数据且层级不深,则
ref
和reactive
中可任选一个; - 如果需要一个对象类型的响应式数据且层级较深,则推荐使用
reactive
; - 如果不想因区分使用场景烦恼,则直接使用
ref
。