MST

星途 面试题库

面试题:Vue中Composition API的响应式原理及简单实践

请阐述Vue Composition API中ref和reactive创建响应式数据的原理及区别。并举例说明如何使用Composition API实现一个简单的计数器功能,要求数据是响应式的,且能在模板中正确显示和更新。
35.6万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

ref 和 reactive 创建响应式数据的原理及区别

  1. 原理
    • ref
      • ref 是用来创建一个包含响应式数据的引用。它通过 Object.defineProperty() 方法将传入的值包装成一个带有 value 属性的对象,并对该 value 属性进行数据劫持,当访问或修改 value 时,会触发依赖收集和更新视图的操作。例如,const count = ref(0),实际上 count 是一个类似 { value: 0 } 的对象,Vue 对 value 进行了响应式处理。
    • reactive
      • reactive 是基于 Proxy 实现的。它直接对传入的对象进行代理,通过 Proxy 拦截对象的各种操作(如读取属性、设置属性等),从而实现依赖收集和触发更新。例如,const state = reactive({ count: 0 }),Vue 会使用 Proxy 代理 state 对象,当访问或修改 state.count 时,能感知到变化并更新视图。
  2. 区别
    • 数据类型
      • ref 适用于基本数据类型(如 numberstringboolean 等)和对象,当传入基本数据类型时,会被包装成一个具有 value 属性的对象。而 reactive 只能用于对象(包括数组和普通对象),不能用于基本数据类型,因为 Proxy 只能代理对象。
    • 访问方式
      • 使用 ref 时,在模板中可以直接使用 ref 变量名,在 JavaScript 代码中访问响应式数据需要通过 .value,例如 const num = ref(10); console.log(num.value)。而使用 reactive 创建的响应式数据,无论是在模板还是 JavaScript 代码中,都直接访问对象的属性,如 const obj = reactive({ num: 10 }); console.log(obj.num)
    • 深层响应式
      • reactive 创建的对象默认是深层响应式的,即对象内部嵌套的对象属性变化也能被检测到。ref 如果传入的是对象,内部对象属性变化默认不会触发更新,需要使用 toRefstoRef 等方法处理后才能实现深层响应式。

使用 Composition API 实现简单计数器功能

<template>
  <div>
    <p>计数器: {{ count.value }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const count = ref(0);

const increment = () => {
  count.value++;
};

const decrement = () => {
  if (count.value > 0) {
    count.value--;
  }
};
</script>

在上述代码中,使用 ref 创建了一个响应式的计数器 count。在模板中直接使用 count 来显示计数器的值,通过点击按钮调用 incrementdecrement 方法来更新 count.value,从而实现计数器的增加和减少功能,并且视图会随着 count 的变化而更新。

如果使用 reactive 实现,代码如下:

<template>
  <div>
    <p>计数器: {{ state.count }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

<script setup>
import { reactive } from 'vue';

const state = reactive({
  count: 0
});

const increment = () => {
  state.count++;
};

const decrement = () => {
  if (state.count > 0) {
    state.count--;
  }
};
</script>

这里使用 reactive 创建了包含 count 属性的响应式对象 state,在模板和方法中直接访问 state.count 来实现计数器功能。