首页 > 编程笔记 > JavaScript笔记
阅读:7
Vue3 reactive()函数的用法(附带实例)
我们学会了利用 ref() 函数定义包含单个数据的响应式对象的方法,那么在应用中如果需要定义包含多个数据的响应式对象该怎么实现呢?Vue3 提供了 reactive() 函数,让开发者可以一次性定义包含多个数据的响应式对象。
reactive() 函数接收一个包含 n 个基础类型或对象类型属性数据的对象参数,它会返回一个响应式的代理对象,一般我们称此对象为“reactive对象”。在 JavaScript 或模板中可以通过 reactive 对象直接读取或更新参数对象中的任意属性数据。
需要强调一点,reactive() 函数进行的是一个深度响应式处理。也就是说,当我们通过 reactive 对象更新参数对象中的任意层级属性数据后,都会触发页面的自动更新。
请读者思考下方代码:
在模板中通过 state 对象来读取内部的 3 个对象进行动态显示,同时将返回的 3 个函数分别绑定到 3 个按钮的点击事件上。运行代码,初始页面效果如下图所示。

图 1 初始页面效果
依次点击“更新msg”、“更新person”、“更新courses”按钮,页面会自动更新显示,如下图所示。

图 2 点击“更新msg”按钮后的页面效果

图 3 点击“更新person”按钮后的页面效果

图 4 点击“更新courses”按钮后的页面效果
reactive() 函数进行的是深度响应式处理,结合刚才的 person 属性来说,不仅直接更新 person 对象会触发页面更新,更新 person 对象中的任意属性(name 或 age)也会触发页面更新,甚至我们给 person 对象添加一个新属性或删除已有属性,页面同样会更新。
将 updatePerson() 函数修改为下方代码:
reactive() 函数定义的数组数据同样进行的是深度响应式处理,我们不仅可以通过调用数组方法进行响应式更新,还可以通过下标进行响应式更新。将 updateCourses() 函数修改为下方代码:
我们直到,先给 ref() 函数传入一个对象或数组数据,再通过 ref 对象来操作对象或数组的内部数据,发现也是响应式的,这是为什么呢?因为一旦 ref() 函数内部的 value 数据是对象或数组,就会自动先创建一个包含此对象或数组的 reactive 对象,也就是代理对象,再保存给 ref 对象的 value,比如下方代码:
reactive() 函数接收一个包含 n 个基础类型或对象类型属性数据的对象参数,它会返回一个响应式的代理对象,一般我们称此对象为“reactive对象”。在 JavaScript 或模板中可以通过 reactive 对象直接读取或更新参数对象中的任意属性数据。
需要强调一点,reactive() 函数进行的是一个深度响应式处理。也就是说,当我们通过 reactive 对象更新参数对象中的任意层级属性数据后,都会触发页面的自动更新。
请读者思考下方代码:
<div id="app"> <ul> <li>msg: {{state.msg}}</li> <li>person: {{state.person}}</li> <li>courses: {{state.courses}}</li> </ul> <button @click="updateMsg">更新 msg</button> <button @click="updatePerson">更新 person</button> <button @click="updateCourses">更新 courses</button> </div> <script> const { createApp, reactive } = Vue createApp({ setup(props, context) { // 使用 reactive 函数定义包含多个数据的响应式对象 const state = reactive({ msg: 'Hello World!', // 基础类型 person: { name: 'Tom', age: 22 }, // 对象类型 courses: ['JavaScript', 'BOM', 'DOM'], // 数组类型 }); // 更新字符串 msg 的函数 const updateMsg = () => { state.msg += '--'; }; // 更新对象 person 的函数 const updatePerson = () => { state.person = { name: 'Jack', age: 33 }; }; // 更新数组 courses 的函数 const updateCourses = () => { state.courses = ['JavaScript2', 'BOM2', 'DOM2']; }; return { state, updateMsg, updatePerson, updateCourses, }; }, }).mount('#app'); </script>上方代码先使用 reactive() 函数定义了包含基础类型、对象类型和数组类型的 3 个属性数据的响应式对象 state,然后分别定义了更新字符串 msg、更新对象 person 和更新数组 courses 的 3 个函数,最后将 state 对象和这 3 个函数都返回模板中使用。
在模板中通过 state 对象来读取内部的 3 个对象进行动态显示,同时将返回的 3 个函数分别绑定到 3 个按钮的点击事件上。运行代码,初始页面效果如下图所示。

图 1 初始页面效果
依次点击“更新msg”、“更新person”、“更新courses”按钮,页面会自动更新显示,如下图所示。

图 2 点击“更新msg”按钮后的页面效果

图 3 点击“更新person”按钮后的页面效果

图 4 点击“更新courses”按钮后的页面效果
reactive() 函数进行的是深度响应式处理,结合刚才的 person 属性来说,不仅直接更新 person 对象会触发页面更新,更新 person 对象中的任意属性(name 或 age)也会触发页面更新,甚至我们给 person 对象添加一个新属性或删除已有属性,页面同样会更新。
将 updatePerson() 函数修改为下方代码:
const updatePerson = () => { // 指定新的 person 对象 // state.person = {name: 'Jack', age: 33}; // 更新对象中的已有属性 state.person.name += '=='; state.person.age += 2; // 给对象添加新属性 state.person.sex = '男'; // 删除对象中的已有属性 delete state.age; };此时点击“更新person”按钮,这 3 种更新方式都能触发页面更新。需要注意的是,直接添加新属性和删除已有属性在 Vue2 中是不可以触发页面更新的,但在 Vue3 中是可以的。
reactive() 函数定义的数组数据同样进行的是深度响应式处理,我们不仅可以通过调用数组方法进行响应式更新,还可以通过下标进行响应式更新。将 updateCourses() 函数修改为下方代码:
// 更新数组 courses 的函数 const updateCourses = () => { // 指定新的数组 // state.courses = ['JavaScript2', 'BOM2', 'DOM2']; // 通过调用数组方法更新数组元素 state.courses.splice(1, 1, 'Vue2'); // 通过下标更新数组元素 state.courses[2] = 'Vue3'; };点击“更新courses”按钮,这两种方式都能触发页面更新。需要注意的是,在 Vue2 中直接通过下标更新数组元素不可以触发页面更新,但在 Vue3 中是可以的。
我们直到,先给 ref() 函数传入一个对象或数组数据,再通过 ref 对象来操作对象或数组的内部数据,发现也是响应式的,这是为什么呢?因为一旦 ref() 函数内部的 value 数据是对象或数组,就会自动先创建一个包含此对象或数组的 reactive 对象,也就是代理对象,再保存给 ref 对象的 value,比如下方代码:
// 创建 ref 对象,并指定内部初始值为一个人员信息 const person = ref({ name: 'Tom', age: 12 }); // 更新 value 对象内部的 age 属性 person.value.age = 13;更新 age 属性就是一个响应式的数据更新,因为 person.value 是 ref() 函数接收的人员信息的 reactive 对象,也就是代理对象,通过 reactive 对象去更新对象的内部属性,必然是一个响应式的数据更新,页面自然会更新。