每日鸡汤:所有真实的快乐,都来自很久的努力
目录
前言
本篇文章学习,响应式基础
首先,需要了解js中代理proxy的相关知识,我之前整理过一篇文章,仅供大家参
【我不熟悉的javascript】01. 使用new Proxy功能,自定义object的setter 和getter_我有一棵树的博客-CSDN博客_js new proxyproxyhttps://blog.csdn.net/qq_17335549/article/details/117005039 了解完proxy的知识,就可以开始学习vue3的响应式原理了
一、关于响应式
【响应式】这三个字,我在最开始接触前端的时候,是使用css的媒体查询,做【响应式】适配的,简单回顾一下
1. 响应式布局
不同的屏幕、终端,展示不同的样式或布局,使每个尺寸的屏幕都有属于自己的一套赏心悦目的页面设计。
我们在实现响应式布局的时候,主要可以使用css的@media规则,它可以指定一个媒体查询条件和一个css块,
// 在屏幕宽度最小为1000px, 也就是说所有大于1000px的情况
@media screen and (min-width: 1000px) {
.box {
color: red
}
}
使用媒体查询经常在我们写官方网站,做移动端适配的时候使用,这样我们就一套代码走天下,很经典的使用媒体查询的网站是apple 的 官方网站,可以打开控制台,自己体会一下。
2. vue中的响应式
很明显,vue中响应式的概念和上述设计理念是完全不同的两个东西,vue中的响应式是指,我们在修改数据的时候,可以自动的修改模版中的值,而无需手动给页面上渲染该属性的dom重新设置新值,也就实现了数据驱动视图的目的。
举个例子,我们在使用原生js,或者jquery 的时候,更改变量后需要手动更新dom:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./dist/bundle.js"></script>
</head>
<body>
<div id="box"></div>
<script>
let name = 'cat'
document.getElementById('box').innerHTML = name
setTimeout(() => {
name = 'dog'
document.getElementById('box').innerHTML = name
}, 1000);
</script>
</body>
</html>
而vue的响应式,省掉了手动更新数据的操作,直接修改数据就可以做到dom自动更新。
二、使用reactive,ref
1. reactive
用于声明复杂类型的响应式对象,比如数组、对象、map、set,对原始数据类型无效,默认是深层次的响应式,可以监控到内部的变化。
2. shallowReactive
这个是与reacitve对应的,可以声明浅层的响应式
3. ref
可以创建任何类型的响应式,所以我在开发过程中基本上都是用ref,没有用过reactive。但是,使用ref的时候,我们在取值的时候需要加上 .value,总之,使用ref 基本可以覆盖我们项目中的基本需求。
三、响应式原理
关于响应式原理,可以看下官网【深入响应式系统】部分。用我自己的话来整理一下下,仅供我自己巩固和学习使用,又不正确的欢迎指正。
1. 首先学习一个英文单词effect
官网将vue源码中的effect函数翻译成了,【副作用】,乍一听感觉有怪怪的,但是其实【副作用】也是一种【影响】嘛,很合理。
这样理解,因为我们修改了数据,引起了副作用!!!进而引起了一系列的响应式更新,这是一个好的副作用。
2. 依赖和订阅者
在副作用中用到的变量就是依赖(dependency),这样副作用就可以说是依赖的订阅者。换言之,一个函数中,用到的变量就是依赖,函数本身就是变量的订阅者。
依赖的英文dependency,所以怪不得源码中使用deps来标识依赖了。
3.主要逻辑
- 使用proxy
- 调用proxy 中属性name的getter时,给name增加订阅者【他就是个函数形成的集合(不用数组,因为要去重)】
- 调用proxy中属性name的setter事,执行(2)中订阅者数组中,所有的函数
4. watchEffect
这个是一个很有用的api,虽然我经常用computed就满足了绝大多数需求,但是在某依赖的变量修改的时候,需要执行异步操作,比如请求接口,用watchEffect就很好。
5. watchEffect和watch的区别
他俩都可以执行异步操作,但是watchEffect在每次代码加载的时候都会执行,类似有一个初始化的执行,而watch是惰性的,只要依赖不变,就不会执行!!
所以使用watchEffect,请求异步接口还可以省掉初始化的操作,因为每次加载都会执行。
具体的参考官方文档侦听器
总结
总之,学完这一章节,我们需要会用ref,和reactive,虽然绝大多数ref就可以满足需求。并且至少知道什么是响应式了吧!!