实现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集含视频的主要内容,如果未能解决你的问题,请参考以下文章

实现mini-vue3

实现mini-vue3

青训营Pro 前端框架设计理念 - Vue3动机 - 手写实现mini-vue

青训营Pro 前端框架设计理念 - Vue3动机 - 手写实现mini-vue

12mmaction2 行为识别商用级别X3D复现 demo实现 检测自己的视频 Expanding Architecturesfor Efficient Video Recognition(代码片段

如何使用两个片段实现视频和视频列表