一、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. C++初阶(封装+多态--整理的自认为很详细)

    继承 概念:继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类.继承呈现了面向对象程序设计的层次结构,体现了由简单 ...

  2. 微信小程序根据开发环境切换域名

     domain.js // 获取当前账号信息,线上小程序版本号仅支持在正式版小程序中获取,开发版和体验版中无法获取. // envVersion:'develop','trial','release' ...

  3. MySQL 常用到的几个字符处理函数

    修改某字段的内容,用于英文 首先解释用到的函数: CONCAT(str1,str2)字符连接函数 UPPER(str)将字符串改为大写字母 LOWER(str)将字符串改为小写字母 LENGTH(st ...

  4. 我要涨知识——TypeScript 常见面试题(二)

    又是一个年底来了,好大一批人可能又准备跑路了,最近回家待产,翻了翻掘金和 CSDN 发现好多大佬都有大厂 Offer ,看着看着我心动了! 话不多说,赶紧开干,给自己整了一个前端面试小助手--微信小程 ...

  5. 学习ASP.NET Core Blazor编程系列十五——查询

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  6. 1.5.6 NN与2NN-hadoop-最全最完整的保姆级的java大数据学习资料

    目录 1.5.6 NN与2NN 1.5.6.1 HDFS元数据管理机制 1.5.6.2 Fsimage与Edits文件解析 1.5.6.2.1 Fsimage文件内容 1.5.6.2.2 Edits文 ...

  7. elasticsearch倒排索引(全面了解)

    SimpleAI推荐语: 前年转过这篇文章,最近在看检索相关论文,发现又有点忘记倒排索引(inverted index)的具体内容,遂翻出来再看看,不得不说,这个漫画画的太好了,娓娓道来,一看就懂,再 ...

  8. (已转)C++知识图谱

  9. APICloud 平台常用技术点汇总讲解

    ​  平台介绍: 使用 APICloud 可以开发移动APP.小程序.html5 网页应用.如果要实现编写一套代码编译为多端应用(移动APP.小程序.html5 ),需使用 avm.js  框架进行开 ...

  10. Java读取文件后文件被占用

    Java读取文件响应后文件一直被占用问题 原因: 由于是封装的函数,请求和响应对象都是 形参地址 虽然在此函数里关闭了输出流,但是由于有返回值,调用未结束,输出流无法提前关闭 解决: 1:调用函数后, ...