

了解 vue composition-api 原理
source link: https://shenzilong.cn/record/%E6%AF%8F%E6%97%A5%E6%80%BB%E7%BB%93/2021/doc/%E4%BA%86%E8%A7%A3%20vue%20composition-api%20%E5%8E%9F%E7%90%86.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

了解 vue composition-api 原理
写在前面的心得
- 1.
不要在 setup 内直接使用 setInterval 与 setTimeout 这类需要手动清理副作用的 api
- 1.
因为人很容易忘记清理他的副作用,应该自行封装一个类似于计算属性的
- 1.
watch
我对 composition-api 中的 watch 的实现一直很好奇,它到底怎么知道我里面依赖了哪些变量?
例如下面的代码:
import {watchEffect, ref } from "vue"
const msg = ref("后撤步!")
watchEffect(()=>{
console.log(msg.value)
})
setTimeout(()=>{
msg.value = "7777"
},1000)
虽然用了这么久的 composition-api 但我从来都不明白 watchEffect
到底是怎么知道 cb 依赖了 msg 的
我自己猜想的方式有两种:
-
第一种是直接执行一遍 cb, msg 的 getter 内就能知道 cb 依赖了 msg,但 cb 内如果有 if 之类的逻辑就会漏掉一些变量的依赖
const t = Date.now() watchEffect(()=>{ if(Date.now() - t > 500){ console.log(msg.value) // 永远不会被执行 } setTimeout(()=>{ console.log(msg.value) // 只会被执行一次 },10) }) setTimeout(()=>{ msg.value = "7777" },1000)
像这样的代码在
1000ms
后并不会打印msg.value
-
另一种是获取 cb 的源码来进行分析,执行
cb.toString()
得到()=>{ console.log(msg) }
就可以看到里面依赖了 msg ,但如果将 cb 改一下const a = ()=>{ console.log(msg) } const cb = ()=>{ a() }
这时候
cb.toString()
得到的是()=>{ a() }
还是没法知道里面依赖了 msg。
经过对 此处代码 的验证,可以猜测 vue 应该是采用的第一种方案,还是去看 vuejs/composition-api 的代码来研究一下吧
watchEffect
的实现在 src/apis/watch.ts#L368 , 代码如下
export function watchEffect(
effect: WatchEffect,
options?: WatchOptionsBase
): WatchStopHandle {
const opts = getWatchEffectOption(options)
const vm = getWatcherVM()
return createWatcher(vm, effect, null, opts)
}
这里没啥好看的,继续看 createWatcher : src/apis/watch.ts#L205 , 代码如下(精简了代码)
function createWatcher(
vm: ComponentInstance,
source: WatchSource<unknown> | WatchSource<unknown>[] | WatchEffect,
cb: WatchCallback<any> | null,
options: WatchOptions
): () => void {
let running = false
const getter = () => {
// preventing the watch callback being call in the same execution
if (running) {
return
}
try {
running = true
;(source as WatchEffect)(registerCleanup)
} finally {
running = false
}
}
const watcher = createVueWatcher(vm, getter, noopFn, {
deep: options.deep || false,
sync: isSync,
before: runCleanup,
})
}
这里可以看到 16行的 (source as WatchEffect)(registerCleanup)
基本验证了猜测,继续看 createVueWatcher : src/apis/watch.ts#L170
链接到此文档的相关文档
by 崮生 from 崮生 • 一些随笔 🎨,欢迎 赞助本文
本文欢迎分享与聚合,全文转载未经授权( 联系我)不许可。
神仙散棒槌IT源点monaco-editor崮生 • 一些随笔 🎨 赞助我 copyright © 2018.11.6 - 2021.10 湘ICP备18021783号 GIT HUB
Recommend
-
22
The next version of Vue is around the corner and we can already try some new features, like Vue Composition API, which is heavily inspired by React Hooks. A lot of developers are excited about it, others are not so sure. L...
-
11
Vue Composition API 响应式包装对象原理上一篇文章Vue 3.0 最新进展,Composition API中,笔者通过描述Vue Composition API 的最新修...
-
10
作者:陈大鱼头github: KRISACHAN作为新特性 Composition API ,在 Vue3 正式发布之前一段时间就发布过了。距文...
-
21
Vue 3.0 最新进展,Composition API在上一篇文章Vue 3.0 前瞻,体验 Vue Function API,笔者通过尝试
-
8
Vue Composition API vs React Hooks - the core difference Arek Nawo | 05 May 2021 | 4 min read
-
10
BackDiscovering Vue Composition API with examplesMay 25th, 2021 · 6 min read
-
5
目录 场景 hook 的时代意义 React Hooks Vue Composition API 差别 总结 场景 先理解…目录hook 的时代...
-
8
Vue Composition API vs. React HooksReact Hooks were introduced with the React 16.8 update, and since then, they...
-
6
Creating Computed Properties with Vue's Composition API Oct 10, 2022 To create a computed property with the Vue's Composition API, you should call Vue's computed() function. For example, the followin...
-
6
The reactivity API adds many possibilities to the composition API while keeping the code brief. However, you should be aware of some of the pitfalls of reactivity, for exampl...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK