前言
彦祖们,开发 vue3 的时候,我们肯定用过 watchEffect
官网解释:立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。 第一个参数就是要运行的
副作用函数
此时引入了副作用函数
这个概念,那么到底什么是副作用函数
呢?
什么是副作用函数?
其实副作用函数
就是指会产生副作用的函数(...听君一席话,听君一席话)
言归正传,副作用函数
其实就是除了本函数
还有其他函数
能修改本函数
执行效果的函数
比如说,我们写一个函数,这个函数内部修改了 body 标签的 innerHTML
除了这个函数,其他函数也具备修改 body 标签的 innerHTML 能力
此时我们就把这个函数 effect
就是称为副作用函数
js
function effect() {
document.body.innerHTML = 'Hello Daniel Wu'
}
document.body.innerHTML = 'Hello Edision' // 外部可以修改 innerHTML
无副作用函数
相比副作用函数
,我们再来看下无副作用函数
其实也很简单
js
function sum(a, b) {
return a + b
}
这个函数,我们只返回了 a + b 的结果,并不具备任何的副作用(其他外部函数无法影响这个函数的执行结果)
什么是响应式?
现在我们已经知道什么是副作用函数
了,那么我们再来看下什么是响应式
?
响应式
就是指,当数据发生变化的时候,我们希望对应的副作用函数
也能执行的过程
比如说
js
const person = {name:'Daniel Wu',age:18}
function effect() {
document.body.innerHTML = 'Hello ' + person.name
}
effect()
当我们修改 person.name
的时候,我们希望 effect
函数能够执行
当然最简单的方式就是手动执行
js
person.name = 'Edison'
effect() // 手动执行副作用函数
此时 innerHTML 就变成下图所示
那么我们如何让 person.name 发生变化的时候,自动执行副作用函数
呢?
实现响应式
响应式原理
其实思路也很简单,不就是监听 person.name
变化,然后执行副作用函数
监听 person.nam
e 变化? 这不就是八股文中常考的 Proxy
拦截吗?
代码非常简单
js
const person = {name:'Daniel Wu',age:18}
const proxyPerson = new Proxy(person,{
// set 拦截器
set(target,key,value) {
target[key] = value
effect() // 进入拦截器的时候执行 effect 函数
return true
}
})
获取到代理对象后,我们把之前的 person
都替换成代理对象 proxyPerson
完整代码
js
const person = {name:'Daniel Wu',age:18}
const proxyPerson = new Proxy(person,{
// set 拦截器
set(target,key,value) {
target[key] = value
effect() // 进入拦截器的时候执行 effect 函数
return true
}
})
function effect() {
document.body.innerHTML = 'Hello ' + proxyPerson.name
}
proxyPerson.name = 'Edison' // 此时进入 set 函数,自动修改了 innerHTML
总结
以上我们就实现了一个非常简单的响应式副作用函数
其核心就是利用 Proxy
实现 set
拦截,然后在拦截器内部执行副作用函数
下一节我们将学习做一个更通用 effect
函数
写在最后
感谢彦祖们的阅读
个人能力有限
如有不对,欢迎指正 🌟 如有帮助,建议小心心大拇指三连🌟