一、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. 关于led蓝牙控制器ble通信分析

    前言 前几天在网上买了一个led蓝牙控制器,可以用手机app通过蓝牙连接控制rgb led灯,当然这个也是属于ble通信.之前我写过一篇体重称蓝牙通信的,不过那个较为简单,数据也是靠分析出来的. 这次 ...

  2. Linux 使用打印机

    前言 在 deepin 上打印机好使,在我的mint上不好使,简单的查看一下deepin上驱动及软件.安装上就行了. 软件及驱动 ii hpijs-ppds 3.18.12+dfsg0-2 all H ...

  3. 获取联通光猫PT952G的管理员密码

    前言 普通用户的帐号和密码在光猫的背面 输入光猫网关即可跳转到登录界面 但是没有什么权限操作东西,所以我找到了管理员界面 输入 网关+cu.html 即可跳转到管理员界面 例如我这里是http://1 ...

  4. Referenced file contains errors (http://mybatis.org/dtd/mybatis-3-config.dtd). For more information, right click on the message in the Problems View and select "Show Details..."

    mybatis配置文件报错Referenced file contains errors mybatis的配置文件报错 The errors below were detected when vali ...

  5. 外部引入css样式报错Resource interpreted as Stylesheet but transferred with MIME type html/text

    Resource interpreted as Stylesheet but transferred with MIME type html/text 解决方法: 1.将content-type改为t ...

  6. EasyCode全自动单表增删改查!

    需要IDEA下载EasyCode插件 准备好三个基础Base类 分页封装基础 package com.gton.io; import lombok.AllArgsConstructor; import ...

  7. [.NET学习] EFCore学习之旅 -3 一些其他的迁移命令

    1.Update-DataBase  xxx 概述:将数据库回滚到某个版本. 1.首先创建一个表 Dog 2.生成迁移 Add-Migration CreateDogTable 并更新到数据库 Upd ...

  8. 【每日一题】【找到位置返回&升序数组中第K大就是n-K小】2022年1月17日-NC88 寻找第K大

    描述有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数. 给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在. 方法 ...

  9. Android-helloword

    环境早已配置完毕,就是后来选择API的时候出现了一点问题,唉,追求时尚,选择最新版本的API,结果就悲剧了,跑不起来,也找不到原因.后来换成Android 4.22 17API Level就行了... ...

  10. 搭建漏洞环境及实战——在Windows系统中安装WAMP

    安装成功之后,打开显示 链接:https://pan.baidu.com/s/1NpU7fUYOO_CSM8dNXKdnCw 提取码:mxvw