实现mini-vue3-更新2集含视频
Posted 阿锋不知道丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现mini-vue3-更新2集含视频相关的知识,希望对你有一定的参考价值。
点击下面链接看视频
初始化项目
yarn init -y
vue3源码采用的是monorerpo的管理方式,我们这就简单点的方式
创建包
集成typescript
注意如果没有安装typescript需要先安装typescript
npx tsc --init
集成jest
yarn add jest @types/jest --dev
注意安装之后还是不能识别spec.ts文件
需要在ts.config文件中配置
配置测试脚本命令
配置ts.config
解决jest不兼容esmodule的问题
配置一下babel
https://jestjs.io/docs/getting-started
安装插件jest
实现收集依赖
先创建effect.spec.js
describe('effect', () =>
it("enter", () =>
const af = reactive(
age: 1
)
/**
* 所谓的收集依赖就是将effect下面的回调函数fn get的时候先放在一个容器中
* set的时候在执行所有被收集起来的fn
*/
let newAge
effect(() =>
newAge =af.age + 1
)
expect(newAge).toBe(2)
af.age++
expect(newAge).toBe(3)
)
)
配置ts.config使其兼容es6
reactive.spec.ts
import reactive from '../reactive'
describe("reactive", () =>
it("enter", () =>
const obj = a: 1
const proxyObj = reactive(obj)
expect(proxyObj).not.toBe(obj)
expect(proxyObj.a).toBe(1)
)
)
下面代码完成上面测试
reactive.ts
export function reactive(raw)
return new Proxy(raw,
get(target, key)
const res = Reflect.get(target, key)
// 依赖收集
return res
,
set(target, key, value)
const res = Reflect.set(target, key, value)
return res
)
effect.ts
let activeEffect
class ReactiveEffect
fn: any
constructor(fn)
this.fn = fn
run()
activeEffect = this
this.fn()
/**
* 依赖收集 收集的就是ReactiveEffect的实例
*
*/
export function effect(fn)
// fn
const _effect = new ReactiveEffect(fn)
_effect.run()
// target->key->dep
//收集依赖
let targetMap = new Map()
export function track(target, key)
let depsMap = targetMap.get(target)
if (!depsMap)
depsMap = new Map()
targetMap.set(target, depsMap)
let dep = depsMap.get(key)
if (!dep)
dep = new Set()
depsMap.set(key, dep)
dep.add(activeEffect)
//触发set 更新
export function trigger(target, key)
let depsMap = targetMap.get(target)
let dep = depsMap.get(key)
for (let effect of dep)
effect.run()
reactive.ts 添加量函数
完成和effect相关的功能
runner
一句话概括这个功能:effect函数会有一个返回一个可执行函数,并且这个函数返回值是fn return出来的值
测试用例
it("runner", () =>
let a = 1
const runner = effect(() =>
a++
return 'a'
)
expect(a).toBe(2)
const r = runner()
expect(a).toBe(3)
expect(r).toBe('a')
)
在effect 函数中return
在run方法中return
scheduler
scheduler 就是 effect能传入的第二个参数,而且这个参数应该是个函数 一开始不会被调用
等响应式对象再次更新的时候 会发现 scheduler会被调用 而第一个参数的回调函数不会再被调用了
测试用例
it("scheduler", () =>
let dummy
let run: any
const scheduler = jest.fn(() =>
run = runner
)
const obj = reactive( foo: 1 )
const runner = effect(
() =>
dummy = obj.foo
,
scheduler
)
// scheduler 就是 effect能传入的第二个参数,而且这个参数应该是个函数 一开始不会被调用
expect(scheduler).not.toHaveBeenCalled()
expect(dummy).toBe(1)
// 等响应式对象再次更新的时候 会发现 scheduler会被调用 而第一个参数的回调函数不会再被调用了
obj.foo++
expect(scheduler).toHaveBeenCalledTimes(1)
expect(dummy).toBe(1)
// 调用runner
run()
expect(dummy).toBe(2)
)
stop
调用stop方法的runner函数 会有一次让响应式更新失效的情况
it("stop",()=>
let dummy;
const obj = reactive(props:1)
const runner = effect(()=>
dummy = obj.prop
)
obj.prop = 2
expect(dummy).toBe(2)
stop(runner)
obj.prop = 3
//可以看到没有立即更新为3 因为上面的runner调用了stop方法
expect(dummy).toBe(2)
runner()
expect(dummy).toBe(3)
)
思路:让当前key 对应的dep 里面的依赖 被删除
以上是关于实现mini-vue3-更新2集含视频的主要内容,如果未能解决你的问题,请参考以下文章
青训营Pro 前端框架设计理念 - Vue3动机 - 手写实现mini-vue
青训营Pro 前端框架设计理念 - Vue3动机 - 手写实现mini-vue
12mmaction2 行为识别商用级别X3D复现 demo实现 检测自己的视频 Expanding Architecturesfor Efficient Video Recognition(代码片段