vue3中ref创建和reactive_对象类型的响应式数据

在Vue 3中,refreactive 是用于创建响应式数据的两种主要方法,它们各有侧重点和适用场景,主要区别在于处理基本类型和对象类型的数据上。

ref

ref 主要用于创建基本类型(如字符串、数字、布尔值)的响应式数据,但它也可以用来包裹对象或者数组,使其整体成为一个响应式引用。使用 ref 创建的数据,访问其实际值时需要通过 .value 属性。

示例:
import { ref } from 'vue';

const count = ref(0); // 基本类型
console.log(count.value); // 访问值

const person = ref({ name: 'Alice' }); // 对象类型
console.log(person.value.name); // 访问对象属性

reactive

reactive 则更适用于创建对象或数组这类复杂类型的响应式数据,它不会像 ref 那样返回一个带有 .value 的包裹对象,而是直接返回原对象,使得你可以在模板和代码中直接访问其属性而不需要额外的 .value

示例:
import { reactive } from 'vue';

const state = reactive({ count: 0, name: 'Bob' });

console.log(state.count); // 直接访问
state.count++; // 改变也会触发视图更新

在vue页面中应该怎么写

HTML部分
<template>
    <div class="person">
        <h2>{{ name }}</h2>
        <h2>{{ age }}</h2>
        <h2>{{ tel }}</h2>
        <!-- 修改名字按钮 -->
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changeTel">修改联系方式</button>
    </div>
</template>
js部分

<script lang="ts">
// 导出默认组件,用于让父组件决定要渲染什么内容
export default {
    name: "Person",
    // 定义一个组件,名称为"Person"
}
</script>
<script setup lang="ts">
import { ref } from "vue";

const name = ref("zhangsan"); // 姓名,初始值为"zhangsan"
const age = ref(18); // 年龄,初始值为18
const tel = ref("123456789"); // 电话,初始值为"123456789"


const changeName = () => {
    name.value = "李四";
};


const changeAge = () => {
    age.value += 1;
};


const changeTel = () => {
    tel.value = "4353456456";
};


</script>

css部分
<!--
 <style scoped>
 </style>
 -->
<!-- 
该注释块位于<style scoped>标签内,用于对样式文件进行说明。
此处不涉及具体的函数或类定义,因此无需参数和返回值说明。
 scoped属性表示这些样式仅适用于当前组件,避免全局样式污染。
此段代码的主要作用是定义组件的内部样式,以实现对组件样式的定制和控制。
 -->
<style scoped>
.person {
    /* 设置高度为100% */
    height: 100%;
    /* 设置背景色为白色 */
    background-color: #fff;
    /* 隐藏滚动条 */
    overflow: hidden;
    /* 为绝对定位准备 */
    position: relative;
    /* 设置底部padding为50px */
    padding-bottom: 50px;
    /* 设置边框框大小 */
    box-sizing: border-box;
    background-color: antiquewhite;
}

h2 {
    color: red;
    /* 设置标题颜色为红色 */
}
</style>

总结

  • 对于基本类型,虽然两者都可以用,但通常推荐使用 ref,因为它能清晰地表明这是一个独立的值。
  • 对于对象或数组这类复杂类型reactive 更为合适,因为它提供了更自然、直接的访问方式,无需通过 .value,更适合处理多层级的数据结构。

选择 ref 还是 reactive,关键在于理解你的数据结构以及是否需要直接访问性。在实际开发中,根据具体需求灵活选择这两个工具来构建高效、易于维护的响应式应用。

### Vue3 中 `ref` `reactive` 的响应式实现原理 #### 一、Vue3 响应式的整体机制 Vue3 使用了一种基于 Proxy 的全新响应式系统,取代了 Vue2 中的 Object.defineProperty 方法。Proxy 提供了一个更强大灵活的方式来拦截对象的操作行为[^1]。 当通过 `ref` 或 `reactive` 定义一个响应式变量时,Vue3 实际上会利用 JavaScript 的 Proxy 来追踪这些变量的变化,并在变化发生时通知视图更新。 --- #### 二、`ref` 的响应式实现原理 `ref` 是用来定义基本类型的响应式数据的一种方式。它内部实际上是一个包装器,将传入的值存储在一个带有 `.value` 属性的对象中。这样做的目的是为了使该值可以被检测到其变更。 以下是其实现的关键点: - 当调用 `ref(value)` 时,如果传递的是一个对象,则会自动将其转换为 `reactive` 类型;如果是原始类型(如字符串、数字等),则保持不变。 - 在模板或其他地方访问 `ref` 数据时,Vue 自动解包 `.value`,使得开发者无需显式书写 `.value` 即可获取实际值[^3]。 代码示例展示如何使用 `ref` 并观察其工作流程: ```javascript import { ref } from &#39;vue&#39;; const count = ref(0); // 创建一个 ref 对象 console.log(count.value); // 输出初始值 0 count.value++; // 修改 .value 属性触发响应式更新 console.log(count.value); // 输出修改后的值 1 ``` --- #### 三、`reactive` 的响应式实现原理 `reactive` 主要用于处理复杂的嵌套对象结构。它的核心是通过 Proxy 拦截对对象属性的各种操作(读取、设置、删除等)。具体来说: - 调用 `reactive(obj)` 后返回的新对象是对原对象的一个代理版本。 - 如果尝试访问或更改此代理对象上的任何属性,都会触发相应的 getter setter 钩子函数。 - 这些钩子函数负责记录依赖关系以及后续的通知过程。 下面是一段简单的例子说明 `reactive` 的功能: ```javascript import { reactive } from &#39;vue&#39;; const state = reactive({ name: &#39;Alice&#39;, age: 25, }); state.age += 1; // 更改年龄属性触发响应式更新 console.log(state.name, state.age); // 打印 Alice 新的年龄值 ``` 需要注意的一点是,由于 `reactive` 返回的是一个新的代理实例,因此不能直接对其源对象进行赋值或者比较相等问题。 --- #### 四、两者的对比分析 尽管两者都服务于相同的最终目标——建立响应式链接,但在某些方面存在差异: - **适用范围**: - `ref`: 推荐用于简单基础类型的数据声明; - `reactive`: 更适合管理具有多层嵌套特性的复杂状态树。 - **性能开销**: - `ref` 添加额外一层封装 (`.value`) ,可能稍微增加内存消耗; - `reactive` 则直接作用于整个对象层次之上,通常效率更高一些。 总结而言,在选择工具之前应该考虑具体的业务需求个人偏好等因素再做决定。 --- ### 结论 无论是采用 `ref` 抑或是 `reactive` 方式来构建应用中的动态交互逻辑,背后均依托着强大的 Proxy 技术支持完成高效的双向绑定效果。理解清楚各自的特性有助于我们写出更加优雅简洁且易于维护的应用程序代码[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值