一、setup文件的认识

  特点1:script 中间的内容就是一个对象

  特点2:script 在第一层 定义的方法 或者 变量 => 就是这个对象 属性  => 顶层的绑定回被暴露给模板(模板可以直接使用这个变量)

  特点3:setup 默认执行生命周期beforeCreate created
  注意:这个对象 => 就是当前这个组件实例

二、什么是响应式api

  处理 数据 => 我们把页面写的数据,需要动态改变的数据 => 叫做  响应式数据 => 数据改变视图中使用了这个数据,这个数据回对应的       响应式数据底层实现 => vue3 => Proxy

  可以把数据变成响应式api 的方法叫做响应式 api
  什么是响应式数据:就是数据改变 视图对应更新
 

三、在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()

  作用:将复杂的数据类型变成响应式数据

  语法:let data=reactive({处理的数据})
  特点:1. 就是proxy代理可以将对象中第一层的属性变成响应式,不用递归,提供性能优化。2. 就是 proxy 代理的数据时对象,这个对象中有深层次,它会实现懒代理(就是用户只有在使用了这个数据,才会将这个数据变为响应式数据)
<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的更多相关文章

  1. Vue3中的响应式对象Reactive源码分析

    Vue3中的响应式对象Reactive源码分析 ReactiveEffect.js 中的 trackEffects函数 及 ReactiveEffect类 在Ref随笔中已经介绍,在本文中不做赘述 本 ...

  2. (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门

    http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...

  3. Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门

    Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可以提高系统 ...

  4. vue3剖析:响应式原理——effect

    响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...

  5. 有关CSS中字体响应式的设置

    在进行页面响应式设计中,往往需要根据屏幕分辨率来显示不同大小的字体.通常的做法是通过media queries给不同的分辨率指定不同的字体样式,例如: body { font-size: 22px; ...

  6. CSS中字体响应式的设置

    在进行页面响应式设计中,往往需要根据屏幕分辨率来显示不同大小的字体.通常的做法是通过media queries给不同的分辨率指定不同的字体样式,例如: body { font-size: 22px; ...

  7. html中的响应式图片

    html中的响应式图片 img sizes 指定屏幕尺寸 srcset 指定可以使用的图片和大小,多个使用逗号分隔,需要指定图片的真实宽度,个人觉得没有picture好用 <img sizes= ...

  8. bootstrap中图片响应式

    主要解决的是在轮播图中图片响应式的问题 目的 各种终端都需要正常显示图片 移动端应该使用更小(体积)的图片 实现方式 给标签添加两个data-属性(如:data-img-sm="小图路径&q ...

  9. Vue.set 向响应式对象中添加响应式属性,及设置数组元素触发视图更新

    一.为什么需要使用Vue.set? vue中不能检测到数组和对象的两种变化: 1.数组长度的变化 vm.arr.length = 4 2.数组通过索引值修改内容 vm.arr[1] = ‘aa’ Vu ...

  10. Css3中的响应式布局的应用

    Media Queries直译过来就是“媒体查询”,在我们平时的Web页面中head部分常看到这样的一段代码: <link href="css/reset.css" rel= ...

随机推荐

  1. Python模块大全之《 os模块》

    ️前言: os 模块提供了非常丰富的方法用来处理文件和目录.是Python基础必备的,所以我用了6000字详细讲述了绝大部分os模块提供的方法,方法如下 方法一.os.makedirs()和os.re ...

  2. python进阶(28)import导入机制原理

    前言 在Python中,一个.py文件代表一个Module.在Module中可以是任何的符合Python文件格式的Python脚本.了解Module导入机制大有用处. 1. Module组成 一个.p ...

  3. 安装mySql 出现 one more product requirements have not been satisified

    安装mySql 出现 one more product requirements have not been satisified 原因是缺少一些依赖环境. 在弹出的对话框中点击 否. 然后点击执行, ...

  4. JDK卸载

    JDK卸载 从环境变量里的JAVA_HOME里找到jdk的主程序,删掉 把JAVA_HOME删掉,在把path里跟java_home相关的也删掉 在cmd里运行java-version

  5. 单一JVM同步锁实现

    同步锁实现 一.背景 在并发场景下,需要单一线程或限定并发数操作某些逻辑,这时候就需要用到一个锁来保证线程安全. 二.思路 使用ConcurrentHashMap实现,但只支持同一个jvm下的线程(暂 ...

  6. hook详解和应用

    一.hook的作用区域 1.客户端的过程 链接服务器 拿回资源 渲染(解析资源)资源 初始化(自执行) 页面逻辑 等待用户输入 加密数据 提交数据 2.hook的本质 在这些流程任意环节中插入自己的代 ...

  7. .NET周报【12月第2期 2022-12-15】

    国内文章 九哥聊Kestrel网络编程第一章:开发一个Redis服务器 https://mp.weixin.qq.com/s/HJYnBE-7wbvkAYHxQaq3eQ 我和拥有多个.NET 千星开 ...

  8. java中生成随机数

    本文主要讲述java中如何生成随机数. public class RandomTest { public static void main(String[] args) { // 生成随机数 方法1: ...

  9. Jmeter在结果树中查看响应数据为空

    今天遇到了一个比较尴尬的问题,吭哧吭哧了大半天,后来咨询了开发SO的一下解决了. 问题: 在调用接口时取样器结果中显示response code:200, response message:OK,但是 ...

  10. 何为GUI???

    1.GUI是什么–简介 GUI的全称为Graphical User Interface,图形化界面或图形用户接口,是指采用图形方式显示的计算机操作环境用户接口.与早期计算机使用的命令行界面相比,图形界 ...