vue3中的ref与reactive

摘要

在vue3直接定义变量不是响应式数据

在vue3中定义变量更改变量页面是显示不出来的

在按钮中绑定一个函数,当我点击它的时候发生改变str值

点击前

点击后

点击后控制台显示更改数据,而页面中不显示数据,这就是vue3没触发响应式

使用ref和reactive可以完美结局,以下文章讲述如何使用ref和reactive来进行响应式操作

一、ref

ref是一个函数,是vue组合式api中的一个方法,主要作用就是定义一个响应式的数据、

复制代码
<template>
    <div>
        <p>
            {{ msg }}
        </p>
        <button @click="handleClick">更新数据</button>
    </div>
</template>

<script lang="ts" setup>

import { ref } from 'vue';

// 定义变量
let msg: any = ref("你好世界")
// 绑定点击事件
let handleClick = () => {
    console.log(msg);

}

</script>

当我们点击更新变量得到是是一个ref对象

更改值操作-----------------------------(页面同步)

我们要获取value值,这样才能响应式

复制代码
<template>
    <div>
        <p>
            {{ msg }}
        </p>
        <button @click="handleClick">更新数据</button>
    </div>
</template>

<script lang="ts" setup>

import { ref } from 'vue';

// 定义变量
let msg: any = ref("你好世界")
// 绑定点击事件
let handleClick = () => {
    // 修改数据必须加上value,因为被ref包裹的变量是一个ref对象
    msg.value = "你好地球"
    console.log(msg.value, ".value方法")

}

</script>

当我再次点击更新数据

直接发生响应式变化

l另外补充

复制代码
    // unref可以直接提取ref定义的value值
            console.log(unref(msg), "unref方法")
            // isRef判断是不是一个ref定义的数据,是就返回true不是就返回false
            console.log(isRef(msg), "isRef方法")

以后使用ref尽量使用.value

二、reactive

*reactive定义多个数据的响应式,返回的是一个proxy代理对象,被代理的对象叫做目标对象

reactive内部是通过es6的proxy实现的,通过代理对象将目标对象转为响应式数据

复制代码
<template>
    <div>
        <p>
            名字:{{ msg.name }}<br>
            年龄:{{ msg.age }}<br>
            性别:{{ msg.sex }}
        </p>
        <button @click="handleClick">更新数据</button>
    </div>
</template>

<script lang="ts" setup>

import { ref, reactive } from 'vue';

// 定义变量
let msg: any = reactive({
    name: "张三",
    age: 20,
    sex: "男"
})
// 绑定点击事件
let handleClick = () => {

    console.log(msg, 'proxy代理对象')

}

</script>

页面输出

更改值操作-----------------------------(页面同步)

复制代码
<template>
    <div>
        <p>
            名字:{{ msg.name }}<br>
            年龄:{{ msg.age }}<br>
            性别:{{ msg.sex }}<br>
            爱好:{{ msg.pin }}
        </p>
        <button @click="handleClick">更新数据</button>
    </div>
</template>

<script lang="ts" setup>

import { ref, reactive } from 'vue';

// 定义变量
let msg: any = reactive({
    name: "张三",
    age: 20,
    sex: "男",

})
// 绑定点击事件
let handleClick = () => {

    msg.name = "李四"
    //在vue2中不先定义直接添加属性会导致视图不更新,解决办法this.$set
    //  在vue3中使用reactive可以
    msg.pin = "健身"
    console.log(msg, 'proxy代理对象')

}

</script>

使用reactive可以直接修改数据而且可以添加没定义的数据

三、ref与reactive区别?

1、ref区别

通过ref定义的基本数据类型

复制代码
<template>
    <div>
        <p>
            {{ m1 }}
        </p>
        <button @click="handleClick">更新数据</button>
    </div>
</template>

<script lang="ts" setup>

import { ref, reactive } from 'vue';

// 定义变量
// 通过ref定义的基本数据类型
let m1 = ref("我是张三");

// 绑定点击事件
let handleClick = () => {
    // 只要通过ref定义的基本数据类型,是一个ref对象,修改数据必须加上.value
    m1.value = "我是李四";
}

</script>

通过ref定义的复杂数据类型

复制代码
<template>
    <div>
        <p>
            {{ m2.wifi.title }}
        </p>
        <button @click="handleClick">更新数据</button>
    </div>
</template>

<script lang="ts" setup>

import { ref, reactive } from 'vue';

// 定义变量
// 通过ref定义的复杂的数据类型
let m2 = ref({
    name: "小鸟",
    wifi: {
        title: "苹果",
    },
});

// 绑定点击事件
let handleClick = () => {
    // 只要通过ref定义的复杂数据类型,是一个ref对象,只是内部会自动变成reactive代理对象的形式
    m2.value.wifi.title = "香蕉";
    console.log(m2);

}

</script>

2、reactive区别

reactive不能定义基本数据类型,只能定义复杂的数据类型

复制代码
<template>
    <div>
        <p>
            {{ m3.wifi.title }}
        </p>
        <button @click="handleClick">更新数据</button>
    </div>
</template>

<script lang="ts" setup>

import { ref, reactive } from 'vue';

// 定义变量
// 通过reactive定义的复杂的数据类型,注意reactive不能定义基本数据类型
let m3 = reactive({
    name: "猴子",
    wifi: {
        title: "香蕉",
    },
});

// 绑定点击事件
let handleClick = () => {
    // 只要通过reactive定义的复杂的数据类型,是一个proxy代理对象
    m3.name = "蜜蜂";
    m3.wifi.title = "糖水";
    console.log(m3);


}

</script>

3、reactive小问题

reactive弊端:赋值一一对应赋值页面可以响应式,页面更新

而整体赋值页面会渲染不上,只有控制台会有变化,而页面中无法更新

将数据obj对象可以直接赋值给reactive定义的m3中,但是不是响应式的(ref是可以的)

ref可以这样整体赋值,但是到后面得加.value

reactive整体赋值解决方法

方法一

创建这个arr\[\]对象可以是空对象!!

方法二

使用****Object.assign(原数据, 新数据)、

对象中添加多个新属性,则通过 **Object.assign(原数据, 新数据)**创建新对象

复制代码
Object.assign(m3, obj)

方法三

使用forEach

使用forEach必须是数组形式

总结

ref和reactive是vue3组合式api中最重要的响应式api

ref是用来处理基本数据类型,reactive是用来处理复杂的数据类型

如果用ref处理复杂的数据类型,那么内部会自动将复杂的数据类型转为reactive代理对象的形式

ref内部:通过value属性添加getter,setter来实现数据的响应式

reactive内部:通过es6中的proxy来实现对对象内部所有的数据进行劫持

注意:ref定义的数据修改数据的时候需要加上.value,reactive不需要

相关推荐
Pedantic1 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘1 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆1 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师2 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆2 小时前
VSCode自动格式化三要素
前端
爱勇宝3 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen4 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user20585561518136 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端