Vue3中的响应式api
一、setup文件的认识
特点1:script 中间的内容就是一个对象
特点2:script 在第一层 定义的方法 或者 变量 => 就是这个对象 属性 => 顶层的绑定回被暴露给模板(模板可以直接使用这个变量)
二、什么是响应式api
处理 数据 => 我们把页面写的数据,需要动态改变的数据 => 叫做 响应式数据 => 数据改变视图中使用了这个数据,这个数据回对应的 响应式数据底层实现 => vue3 => Proxy
三、在vue3 中有哪些常用的响应式API?
响应式核心:
1、ref()
作用:将一个基本数据类型的数据变为响应式
语法:let 变量=ref(处理的数据)
<template>
<div>
<h2>响应式api</h2>
<h2>{{age}}</h2>
<button @click="addAge">change</button>
</div>
</template> <script setup>
import {ref} from 'vue';
// ref 处理的数据
// 1 基本数据类型 => 通过vue2 响应式原理来实现Object.defineProperty()
// 2 处理的复杂的数据类型 => reactive()这个响应式api let age=ref(29); // 通过ref 处理的数据 => 变成响应式
let data=ref({ages:50});
console.log(data,"data") const addAge=()=>{
age.value+=1;
console.log(age);
}
</script> <style> </style>
2、reactive()
作用:将复杂的数据类型变成响应式数据
<template>
<div>
<h2>响应式api</h2> <h2>{{objP.name}}的年龄{{objP.age}}</h2> <button @click="changeName">changeName</button>
<button @click="changeLike">changeLike</button>
</div> </template> <script setup>
import {reactive} from 'vue'; // 作用将复杂的数据类型变成响应式数据
let objP=reactive({
name:"小明",
age:8,
like:{eat:'',play:['']}
}) // reactive()代理数据类型 对象 特点
// 1 就是 proxy 代理可以将对象中第一层的属性变成响应式,不用递归,提供性能优化
// 2 就是 proxy 代理 数据是对象,这个对象中属性有深层次,他会实现懒代理
// 就是用户只有在使用了这个数据,才会将这个数据变为 响应式数据
console.log(objP); const changeName=()=>{
objP.name="lisa"
objP.age+=1;
} const changeLike=()=>{
objP.like.play=[''];
console.log(objP.like); // 使用后深层次数据也变为响应式数据
} </script> <style> </style>
3、readonly()
作用:处理的数据,只能读取不能修改,父组件给子组件数据
语法:let 数据 =readonly(默认数据)
<template>
<div>
<h2>readonly</h2>
<!-- 作用:处理的数据,只能读取不能修改,父组件给子组件数据
语法: let 数据 =readonly(默认数据)
-->
<h2>{{ obj.name }}</h2>
<button @click="change">修改数据</button>
</div> </template> <script setup>
import {readonly} from 'vue'; let obj=readonly({name:'lisa'}); // 通过proxy代理 console.log(obj) const change=()=>{
obj.name="cici"; // 只读的,无法修改
} </script> <style> </style>
4、watchEffect()
作用: 页面更新 就会触发watchEffect 处理函数
语法:watchEffect(( )=>{ })
特点:1 第一次默认执行 处理函数; 2 watchEffect 监听的数据,需要我们写到他的处理函数中,并且 可以监听多个; 3 watchEffect 监听的数据的改变,处理函数就会触发=》获取到最新的数据=》没有旧 的数据
<template>
<div>
<h2>watchEffect 副作用</h2>
<!--
作用: =》 页面更新 就会触发watchEffect 处理函数 语法:watchEffect(()=>{ })
-->
<h2>{{ name }}</h2>
<h2>{{ age }}</h2>
<button @click="addAge">年龄+1</button>
<button @click="changeName">修改name</button>
</div>
</template> <script setup> import {ref,watchEffect} from 'vue'; let age=ref(20);
let name=ref("lisa"); // watchEffect 特点
// 1 第一次执行 处理函数
// 2 watchEffect 监听的数据, 需要我们写到它的处理函数中,并且可以监听多个
// 3 watchEffect 监听数据的改变,获取到新的数据,没有旧数据 // watchEffect(()=>{
// console.log("页面更新了");
// console.log(age.value);// 监听 age 值,只要这个值发生改变,这个watchEffect 他的处理函数就是重新执行,获取到的最新的数据
// console.log(name.value);
// }) // 在watchEffect中做数据处理
watchEffect(()=>{
console.log('页面更新');
if(age.value>30){
console.log('200');
}
})
const addAge = ()=>{
age.value = age.value +1
}
const changeName =()=>{
name.value='小明'
}
</script> <style>
</style>
5、watch()
作用:侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。
语法:watch(数据源,回调函数,配置项)
数据源:监听的数据源、
回调函数:(newVal,oldVal)=>{console.log(newVal,oldVal); // 数据改变会触发次函数的执行 }、
配置项:immediate:true; // 第一次默认监听数据、deep:true; // 监听深度数据
总结watch():1. 首次加载默认不监听,2. 可以监听多个数据源 ,3. 可以处理异步问题
watch() 和 watchEffect() 的区别:
相同点:1. 都是侦听一个或多个响应式数据源,2. 可以处理异步问题
不同点:watchEffect 默认立即监听数据,只能获取到新的数据;而watch 第一次默认不见听数据,可以获取到新旧数据
<template>
<div>
<h2>watch</h2>
<!-- <h2>{{ name }}</h2> -->
<h2>{{ age }}</h2>
<button @click="changeAge">年龄+1</button>
<!-- <button @click="changeName">修改name</button> --> <h2>{{ state.name }}</h2>
<button @click="changeState">修改 reactive 数据类型</button>
</div>
</template> <script setup> import { ref, watch, reactive } from 'vue';
// watch 作用 => 时刻监听数据的改变(响应式数据)
// 语法:watch(数据源,处理函数,配置项)
// 配置项:immediate:true; 首次加载默认监听
// deep:true;监听深度的数据 // // 案例一: 监听数据 ref 类型
// let age=ref(20);
// let name=ref("lisa"); // watch(age,(newVal,oldVal)=>{
// console.log(newVal,oldVal); // 数据改变会触发次函数的执行
// })
// const changeAge = ()=>{
// age.value =age.value +1;
// }
// const changeName =()=>{
// name.value='小明'
// } // 案例2:通过watch 监听某个数据 首次监听到
//添加配置项 immediate:true =》首次监听到
// 监听的深度的数据 =》 deep:true
// let state = reactive({
// name:'张三',
// age:100,
// like:{eat:'吃'}
// })
// watch( ()=>state.like,(newVal,oldVal)=>{
// console.log(newVal,oldVal);
// },{
// immediate:true,
// deep:true
// })
// const changeState = ()=>{
// state.like.eat='小红'
// }
// const changeAge = ()=>{
// age.value +=1
// } // 案例3:watch =>监听多个数据 let age = ref(29) let state = reactive({
name: '张三',
age: 100
}) watch([age, () => state.name], ([newA, newN], [oldA, oldN]) => {
console.log(newA, oldA);
console.log(newN, oldN);
})
const changeState = () => {
state.name = '小红'
}
const changeAge = () => {
age.value += 1
}
//总结 watch
//作用监听 响应式数据
// 特点
// 1默认 第一次不执行,如果需要理解执行添配置项
// 2监听多个数据源
// 3 处理异步问题
//watchEffect 和watch 相同的点和不同点
// 相同点
// 都可以时时刻刻监听某个数据改变,处理异步问题,都可以监听多个数据
//不同点
// watchEffect 默认立即执行 ,watchEffect 只能获取到最新的数据
// watch 默认不立即执行,watch 获取 到新旧数据
</script> <style> </style>
6、computed() 计算属性
作用:后端给的数据不是自己想要的,通过计算属性,把自己数据处理成自己想要的
写法:1. 默认:只用get方法,语法:let 想要的数据=computed({return 计算后的数据 });
2. get 和set 方式:let 想要的数据=computed({get:()=>{return}, set:(value)=>{}})
特点:1. 可以时时刻刻监听数据,根据这个数据,得到我们需要的数据;2. 只能写同步方法
<template>
<div>
<h2>计算属性computed</h2>
<!--
作用:计算属性
1 什么时候使用这个计算属性
后端给的数据,不是自己想要的,通过计算属性,把这个数据处理成自己想要的
2 语法: let 需要的数据=computed(()=>{})
-->
<h2>计算出实际薪资{{total}}</h2>
</div>
</template> <script setup>
import {ref,computed} from 'vue'; // 后端给的一个数据
let salary=ref(0);
const getData=()=>{
setTimeout(()=>{
// 后端给的数据 没有实际的数据
salary.value=2000;
},500);
}
getData(); // // 计算属性的用法: 1 get 属性
// let total=computed(()=>{
// // 处理逻辑 +200
// return salary.value+200;
// }) // 用法2: 具有set 和 get 属性 // 1 什么时候触发get 方法 => 获取这个计算属性的放回置的时候 触发 get方法
// 2 什么时候触发set 方法 => 修改值得时候触发set方法
let total=computed({
get:()=>{
console.log("获取的时候触发");
return salary.value+1000;
},
set:(value)=>{// 第一个参数:设置的值
console.log("设置值的时候触发",value); // 设置total的时候触发这个方法
// 1 通过计算属性get方法 计算出我们需要的数据
// 2 当这个值为 某个值的时候,有需要进行逻辑处理,得到一个新的计算属性的值
setTimeout(()=>{
if(value>=3200){
salary.value=salary.value-200
}
},1000)
}
}) console.log(total);
total.value=6000;
// 计算属性的特点:
// 1 计算属性不能处理异步数据
// 2 时时刻刻观察 我们需要处理的动态数据
</script> <style> </style>
响应式:工具
1、toRefs()
本质:就是将reactive代理对象数据中的属性,属性值 变为 ref处理的数据
语法:toRefs(reactive响应式数据)
<template>
<div>
<h2>{{name}}</h2>
<h2>{{age}}</h2> <button @click="addAge">addAge</button>
</div> </template> <script setup>
import {reactive,toRefs} from 'vue'; // let {age,name}=reactive({
// name:"小明",
// age:8,
// like:{eat:'',play:['']}
// })
// // 直接结构 reactive 响应式数据 => 他的数据不再是响应式数据
// const addAge=()=>{
// age=age+1; // 无法修改
// } let objP=reactive({
name:"小明",
age:8,
like:{eat:'',play:['']}
})
// 我想在视图中直接使用 name,age 和ref 一样
// 本质就是将reactive 代理,对象数据中的属性,值变成ref处理的数据
// 使用vue3中的响应式api => toRefs // 语法: toRefs(reactive响应式数据)
let {age,name}=toRefs(objP); const addAge=()=>{
age.value+=1; // 无法修改
}
</script> <style> </style>
2、toRef()
作用:将reactive代理的数据(这个数据必须是一个对象)中的某个属性变为ref代理
语法:let ref值=toRef(目标对象,属性)
toRefs() 和 toRef() 的区别:toRefs()是把对像中的所有的属性,变成ref进行代理; toRef()是把reactive中的某个属性,变成ref 进行代理
<template>
<div>
<h2>toRef</h2>
<!--
作用:就是将reactive代理的数据,这个数据必须是一个对象,中的某个属性变成ref 代理
语法:let ref值=toRef(目标对象,属性)
-->
<h2>{{stateAge}}</h2>
</div>
</template> <script setup> import {toRef,reactive} from 'vue'
let state=reactive({
age:20,
name:"lisa",
}) let stateAge=toRef(state,'age');
console.log(stateAge);
</script> <style> </style>
3、isRef()、isReactive()、isReadonly()、isProxy()
作用:判断这个变量是不是被这个isxxx这个方法处理了,返回值为布尔值,是就为true,不是就为false
<template>
<div>
<!-- 响应式api工具
isRef =>
isReactive
isReadonly
isxxx => 判断 这个变量是不是被这个isxxx这个方法处理了,是true,不是false -->
</div>
</template> <script setup> import {ref,isRef,isReadonly} from 'vue' let money = ref(1000) // ref 代理了 let obj={name:"lisa"}
console.log(isRef(money)); // 判断这个变量是不是ref代理的 // false
console.log(isReadonly(obj)); // false
</script> <style> </style>
响应式:进阶
1、shollowRef()、shallowReactive()、shallowReadonly()
作用:第一层有这个方法的 功能,只作用于第一层
shollowRef() 第一层的数据是响应式、shallowReactive()第一层的数据是响应式、shallowReadonly() 第一层的数据是只读
<template>
<div>
<h2>shallowReactive</h2>
<!--
shallowReactive => 第一层的数据是响应式
shallowRef => 第一层的数据是响应式
shallowReadonly => 第一层的数据是只读的
作用:浅的,只作用于数据的第一层
-->
<h2>{{state.name}}</h2>
<h2>{{state.like.eat}}</h2>
<button @click="change">改变state
第一层中的数据</button>
<button @click="changeTwo">改变state
第二层中的数据</button>
<button @click="changeAll">同时改变state
第一层和第二层中的数据</button> <h3>{{ objs.name }}</h3>
<h3>{{ objs.like.eat }}</h3>
<button @click="changeR">改变state
第二层中的数据</button>
</div>
</template> <script setup> import {shallowReactive,reactive,toRefs,shallowReadonly} from 'vue'; let state=shallowReactive({
age:20,
name:"lisa",
like:{eat:""}
}) const change=()=>{
state.name="andy"; }
const changeTwo=()=>{
state.like.eat= ""; // 单独是无法修改的,因为它不是第一层数据,不是响应式的数据
}
const changeAll=()=>{
state.name="andy";
state.like.eat= ""; // 添加第一层数据,同时改变,第二层也变成了响应式的数据
} //readonly
let objs = shallowReadonly({
name:'小明',
like:{eat:''}
}) const changeR =()=>{
// objs.name="cici";//无法修改,因为这里的第一层是只读的
objs.like.eat=''; // 这里是可以改变的,因为shallowReadonly只作用于第一层,但是它不是响应式的,无法同步视图更新
console.log(objs.like.eat); //
} // shallowRef() 同理 </script> <style> </style>
Vue3中的响应式api的更多相关文章
- Vue3中的响应式对象Reactive源码分析
Vue3中的响应式对象Reactive源码分析 ReactiveEffect.js 中的 trackEffects函数 及 ReactiveEffect类 在Ref随笔中已经介绍,在本文中不做赘述 本 ...
- (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...
- Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可以提高系统 ...
- vue3剖析:响应式原理——effect
响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...
- 有关CSS中字体响应式的设置
在进行页面响应式设计中,往往需要根据屏幕分辨率来显示不同大小的字体.通常的做法是通过media queries给不同的分辨率指定不同的字体样式,例如: body { font-size: 22px; ...
- CSS中字体响应式的设置
在进行页面响应式设计中,往往需要根据屏幕分辨率来显示不同大小的字体.通常的做法是通过media queries给不同的分辨率指定不同的字体样式,例如: body { font-size: 22px; ...
- html中的响应式图片
html中的响应式图片 img sizes 指定屏幕尺寸 srcset 指定可以使用的图片和大小,多个使用逗号分隔,需要指定图片的真实宽度,个人觉得没有picture好用 <img sizes= ...
- bootstrap中图片响应式
主要解决的是在轮播图中图片响应式的问题 目的 各种终端都需要正常显示图片 移动端应该使用更小(体积)的图片 实现方式 给标签添加两个data-属性(如:data-img-sm="小图路径&q ...
- Vue.set 向响应式对象中添加响应式属性,及设置数组元素触发视图更新
一.为什么需要使用Vue.set? vue中不能检测到数组和对象的两种变化: 1.数组长度的变化 vm.arr.length = 4 2.数组通过索引值修改内容 vm.arr[1] = ‘aa’ Vu ...
- Css3中的响应式布局的应用
Media Queries直译过来就是“媒体查询”,在我们平时的Web页面中head部分常看到这样的一段代码: <link href="css/reset.css" rel= ...
随机推荐
- Python中 or、and 的优先级
上式可以看出 先看 and 输出才为 ture 因此 优先级 and>or
- 数电第六周周结_by_yc
时序逻辑电路的设计要点: ①只有时钟信号和复位信号可以放在敏感列表里: ②使用非阻塞赋值,即使用"<="; ③无需对所有分支进行描述,对于未描述的分支,变量将保持 ...
- 【Java面试指北】Exception Error Throwable 你分得清么?
读本篇文章之前,如果让你叙述一下 Exception Error Throwable 的区别,你能回答出来么? 你的反应是不是像下面一样呢? 你在写代码时会经常 try catch(Exception ...
- JavaEE Day10 JavaScript高级
今日内容 JavaScript ECMAScript:客户端脚本语言标准() BOM对象 DOM对象 事件 学习顺序:DOM-事件-BOM-DOM 一.简单入门 1.DOM 功能:控制HTML文档的内 ...
- 【笔面试题目】Java集合相关的面试题-List、Map、Set等
一.List 1.subList 不会返回新的list对象--与String的subString不同 返回原来list的从[fromIndex,toIndex)之间这一部分的视图,实际上,返回的lis ...
- 【Shell脚本案例】案例3:批量创建100个用户并设置密码
一.背景 新入职员工创建用户 二.常规操作 useradd zhangsan ls /home/ password zhangsan 三.考虑问题 1.实现自动输入密码,将其存到文件中 passwor ...
- python3中的常见知识点2
python3中的常见知识点2 列表与栈和队列 map()函数 python列表遍历的4种方式 参考链接 列表栈和队列 1.列表作为栈使用 栈:先进后出,First In Last Out 使用 ap ...
- Qwt开发笔记(二):Qwt基础框架介绍、折线图介绍、折线图Demo以及代码详解
前言 QWT开发笔记系列整理集合,这是目前使用最为广泛的Qt图表类(Qt的QWidget代码方向只有QtCharts,Qwt,QCustomPlot),使用多年,系统性的整理,本系列旨在系统解说并 ...
- ubuntu1804搭建FTP服务器的方法
搭建FTP服务器 FTP的工作原理: FTP:File Transfer Protocol ,文件传输协议.属于NAS存储的一种协议,基于CS结构. ftp采用的是双端口模式,分为命令端口和数据端口, ...
- JUC源码学习笔记7——FutureTask源码解析,人生亦如是,run起来才有结果
系列文章目录和关于我 一丶我们在哪里会使用到FutureTask 基本上工作中和Future接口 打交道比较多,比如线程池ThreadPoolExecutor#sumbit方法,返回值就是一个Futu ...