news 2026/5/31 6:57:19

vue3基本应用—响应式api

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
vue3基本应用—响应式api

ref

ref 是用来创建响应式引用的主要方法。它通常用于基本数据类型(如字符串、数字、布尔值、对象、数组等)的响应式包装。在模板中可以直接使用,但在 JavaScript 中需要通过 .value 属性来访问或修改它的值
1、ref具有深层次响应式特点,主要针对对象;
2、通过shallowRef创建的响应式,不会深层递归,不具备深层响应式特点;

import { ref } from 'vue'; const count = ref(0); const userName = '洛可可白'; // 在 JavaScript 中访问 console.log(count.value); // 0 count.value++; // 增加计数 // 在模板中访问 // <div>{{ count }}</div> // ref也可以用于获取dom元素 <div><div ref="myDiv"></div> const myDiv = ref(null); myDiv.value.innerHTML = userName;

reactive

reactive 是用来创建响应式对象的方法,适用于处理对象和数组。reactive对象的属性可以在模板和 JavaScript 中直接访问和修改,不需要 .value
1、reactive具有深层次响应式特点;
2、通过shallowReactive创建的响应式,不会深层递归,不具备深层响应式特点;
3、使用reactive创建对象时不要去直接替换reactive关联的对象,会丢失响应式;
4、对reactive的数据进行对象解构时,解构的数据也会丢失响应式;
5、如果将ref作为reactive创建对象的属性,获取该属性值时,不需要解包(无需.value);但是如果将ref作为shallowReactive创建对象的属性时,不会自动解包。

import { reactive } from 'vue'; const state = reactive({ count: 0, userName: '洛可可白' }); // 在 JavaScript 中访问和修改 console.log(state.count); // 0 state.count++; // 增加计数 // 在模板中直接访问 // <div>{{ state.count }}</div> // <div>{{ state.userName }}</div>

ref对比reactive

vue中的响应式是通过Proxy来实现的,Proxy只能拦截对象,无法拦截原始值;那如果需要把原始值转成响应式如何处理?
1、用户自己把原始值包装成对象,再使用reactiveApi;
2、框架层面帮你处理成对象(使用refApi),ref有两种处理方式:
A、如果是原始值,使用Object.defineProperty来实现;
B、如果是对象,使用reactiveApi来实现;
C、reactive响应式内部是由Proxy来实现;

响应式其它API

toRef、toRefs、unRef、readonly、isRef、isReactive、isProxy、isReadonly

import { isReactive, reactive, toRef, isRef, unref, toRefs, shallowReactive, shallowReadonly, readonly, isProxy, } from 'vue' const state = reactive({ count: 1, obj: { value: 1, }, }) // 将响应式对象属性转化为ref const countRef = toRef(state, 'count') // => const countRef = ref(state.count) // 将整个reactive对象的所有属性都转化为ref对象 const refs = toRefs(state) // 取值 => const count = refs.count.value // 判断一个对象是否是ref isRef(countRef) // true // 解包ref对象,如果不是ref直接返回值 unref(countRef) // 1 // 判断是否是reactive isReactive(state) // true isReactive(state.obj) // true reactive是深层次响应式,所以下层对象也是reactive对象 // 创建只读代理 只能获取不能改值 const readObj = readonly(state || countRef) // isProxy 检查一个对象是否由reactive、readonly、shallowReactive、shallowReadonly创建的代理 // 因为ref内部是用了两种方式,所以它并不是单一的Proxy代理实现 isProxy(state)

customRef

customRef 是 Vue 3 响应式系统暴露的一个底层 API,它允许开发者创建具有完全自定义依赖追踪和触发更新逻辑的 ref;customRef 函数接收一个工厂函数,这个工厂函数需要返回一个包含 get 和 set 方法的对象,而这两个方法会收到 track 和 trigger 这两个关键函数作为参数

import{customRef}from'vue';constmyCustomRef=customRef((track,trigger)=>{// 内部可以定义任何你想要的变量letvalue='initial value';return{get(){track();// 依赖收集returnvalue;},set(newValue){value=newValue;trigger();// 触发更新}};});
customRef 实现防抖

这是 customRef 最经典的应用场景:创建一个值在频繁更改时(如输入框输入),只会在最后一次更改后的特定时间后才触发更新
效果:你在输入框中快速打字时,下方的显示不会实时变化,只会在你停止输入 500 毫秒后更新为最终内容。

<template><input v-model="debouncedText"placeholder="试试快速输入..."/><p>防抖后的值:{{debouncedText}}</p></template><script setup>import{customRef}from'vue';// 1. 定义一个通用的防抖 customRef 函数functionuseDebouncedRef(value,delay=500){returncustomRef((track,trigger)=>{const_value=valueconst_debounce=debounce((val)=>{_value=valtrigger()},delay)return{get(){track();// 追踪依赖return_value;},set(newValue){_debounce(newValue)}};});}// 2. 使用它constdebouncedText=useDebouncedRef('',500);</script>

v-model、defineModel(vue3.4)

v-model 既可以实现数据到表单元素之间的双向绑定,也可以用于父子组件之间的数据双向绑定

<!--使用场景一:基本表单组件(将组件实例上的searchText绑定给input的value属性)--><input v-model="searchText"/><!--使用场景二:父子组件双向绑定--><!--当父组件中pageNum发生变化时,子组件会自动更新currentPage的值,同样当子组件的currentPage发生变化时,父组件也会自动更新pageNum的值--><!--父组件--><pagination v-model:page="pageNum"/><!--子组件-->constprops=defineProps({page:{type:Number,default:1}});constemit=defineEmits(['update:page']);constcurrentPage=computed<number|undefined>({get:()=>props.page,set:value=>{emit('update:page',value);}});

defineModel仅用于父子组件之间的数据双向绑定,它只是一个语法糖,内部还是用的props取值以及自定义事件来完成父组件数据的更新,并没有打破单向数据流

<!--父组件--><Home v-model:count1="state.count"v-model:count2="_count1"name="张三"></Home><!--子组件-->constcount1=defineModel('count1')constcount2=defineModel('count2')functionupdate(){count1.value++;count2.value++;}

computed

computed 用于创建计算属性,这些属性的值是基于其他响应式数据源派生出来的。计算属性是惰性求值的,只有当它们的依赖响应式数据发生改变时才会重新计算,对比模板中直接使用函数来实现,它的性能更好
computed值也可以修改,但是computed的设计思想只用来获取值,所以不建议进行修改操作

import { ref, computed } from 'vue' const count = ref(0) const doubleCount = computed(() => count.value * 2) // computed的修改使用 import { computed, isReactive, reactive, ref } from 'vue' const state = reactive({ count: 1, obj: { value: 1, }, }) const count = ref(0) const newCount = computed({ get(value) { return state.count + 10 }, set(value) { count.value = value }, }) setTimeout(() => { newCount.value = newCount.value + 1 }, 2000)

watch

watch 用于观察响应式数据的变化,并在数据变化时执行特定的函数。
1、watch的执行顺序优于computed
2、watch可以监听ref、reactive、computed,以及Getter函数(监听函数返回值),以及数组形式的ref或者reactive
3、watch监听的对象是reactive数据时,监听层级是深层次的
4、如果想要监听reactive对象属性值时,应该使用回调函数形式来监听【watch(()=> getValue, () => {})】

import{ref,watch}from'vue';constcount=ref(0);watch(count,(newValue,oldValue)=>{console.log(`Count changed from${oldValue}to${newValue}`);});functiongetValue(){returnstate.count/2}watch(getValue,(newV,oldV)=>{})watch([_count1,_count2,state,state2],(newV,oldV)=>{},{immediate:true,// 默认false 组件渲染时会执行一次deep:true,// 默认true 深度监听,但是如果监听对象是computed值或者Getter函数时默认就是falseonce:true// 默认false 监听器回调函数只执行一次flush:'post'// dom更新之后执行},)

watchEffect

watchEffect 是一个基于响应式数据源的观察者,当响应式数据源变化时重新执行。
1、会立即执行一次
2、多依赖项监听可以使用watchEffect,而不是watch
3、如果只需要监听reactive对象的某个属性,那么watchEffect函数中只需要用到该属性即可,性能对比watch更优

import{ref,watchEffect}from'vue';constcount=ref(0);constunwatch=watchEffect(()=>{console.log(`Count is now:${count.value}`);});unwatch()// 停止侦听器
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 9:23:04

微信小程序分账系统技术解析:从官方接口到合规架构的选型指南

在小程序生态开发中&#xff0c;分账功能是平台型应用&#xff08;如多商户电商、知识付费分销&#xff09;的核心模块。开发者常面临三重技术困境&#xff1a;官方分账接口灵活性不足、第三方系统合规性存疑、多支付通道整合难度大。本文从技术视角拆解微信小程序分账的实现逻…

作者头像 李华
网站建设 2026/5/31 8:11:57

Kotaemon实体抽取能力在客户工单中的应用

Kotaemon实体抽取能力在客户工单中的应用 在某电信运营商的客服中心&#xff0c;一线坐席每天要处理上千条客户报障信息&#xff1a;从“我家路由器连不上网”到“打印机一直卡纸”&#xff0c;描述五花八门、术语混杂。传统方式下&#xff0c;坐席需手动提取设备型号、故障现象…

作者头像 李华
网站建设 2026/5/31 7:17:25

EmotiVoice语音合成引擎的自动化测试框架介绍

EmotiVoice语音合成引擎的自动化测试框架设计与实践 在AI语音技术飞速发展的今天&#xff0c;用户对语音合成的要求早已超越“能说话”这一基本功能。从虚拟偶像直播到游戏NPC对话系统&#xff0c;再到个性化有声读物生成&#xff0c;人们期待的是富有情感、具备人格化特征、音…

作者头像 李华
网站建设 2026/5/29 21:26:49

EmotiVoice语音合成结果的年龄感控制精度测试

EmotiVoice语音合成结果的年龄感控制精度测试 在虚拟角色越来越“像人”的今天&#xff0c;我们对AI语音的要求早已不再满足于“能说话”——而是要“说得像那个人”。一个设定为天真孩童的角色如果发出低沉沙哑的嗓音&#xff0c;哪怕语法再正确、发音再清晰&#xff0c;也会瞬…

作者头像 李华
网站建设 2026/5/30 2:30:56

【Linux网络编程】应用层协议:HTTP协议

一、认识HTTPHTTP&#xff08;超文本传输协议&#xff09;是互联网通信的基石。它定义了客户端&#xff08;浏览器&#xff09;和服务器之间如何交换数据&#xff08;HTML、图片、视频等&#xff09;。核心特点&#xff1a;应用层协议&#xff1a;基于 传输层/网络层协议 传输 …

作者头像 李华