목차
1. 响应式系统
2. 代码实现
2.1 initState
2.2 Observer/defineReactive
2.3 Dep
1. 반응형 시스템
2. 코드 구현
2.4 Watcher
2.5 小结
웹 프론트엔드 JS 튜토리얼 Vue 소스 코드의 종속성 수집 원칙

Vue 소스 코드의 종속성 수집 원칙

Jul 09, 2018 am 11:14 AM
vue.js

이 글은 Vue 소스코드의 의존성 수집 원리를 주로 소개하는데, 이는 특정 참조 가치를 갖고 있습니다. 이제는 모든 사람과 공유합니다. 도움이 필요한 친구들은 참고할 수 있습니다.

vue는 현재 국내에 있습니다. 웹사이드는 전 세계의 3분의 1을 차지하며, 일상적으로 사용하는 주요 기술 스택 중 하나이기도 합니다. 게다가 Vue 소스 코드를 읽는 기사가 많은 이유도 궁금합니다. 최근 커뮤니티에 등장한 적이 있는데, 이 기회를 빌어 여러분의 글과 토론을 통해 영양분을 조금 배우고 동시에 소스 코드를 읽을 때 어떤 생각을 정리하고 제 생각을 요약하여 몇 가지 글을 작성했습니다. .레벨이 제한되어 있으니 토론메세지를 남겨주세요~

Goal Vue 버전: 2.5.17-beta.0
Vue 소스코드 댓글: https //github.com/SHERlocked...
진술: 기사의 소스 코드 구문은 Flow를 사용했으며 필요에 따라 소스 코드를 삭제했습니다(혼란을 피하기 위해@_@) .풀버전을 보시려면 위의 github 주소를 입력해주세요. 본 글은 연재글 주소는 하단에서 확인하실 수 있습니다~2.5.17-beta.0
vue源码注释:https://github.com/SHERlocked...
声明:文章中源码的语法都使用 Flow,并且源码根据需要都有删节(为了不被迷糊 @_@),如果要看完整版的请进入上面的github地址,本文是系列文章,文章地址见底部~

1. 响应式系统

通过官网的介绍我们知道 Vue.js 是一个MVVM框架,它并不关心视图变化,而通过数据驱动视图更新,这让我们的状态管理非常简单,而这是怎么实现的呢。盗用官网一张图

Vue 소스 코드의 종속성 수집 원칙

每个组件实例都有相应的 Watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

这里有三个重要的概念 ObserveDepWatcher,分别位于src/core/observer/index.jssrc/core/observer/dep.jssrc/core/observer/watcher.js

  • Observe 类主要给响应式对象的属性添加 getter/setter 用于依赖收集与派发更新

  • Dep 类用于收集当前响应式对象的依赖关系

  • Watcher 类是观察者,实例分为渲染 watcher、计算属性 watcher、侦听器 watcher三种

2. 代码实现

2.1 initState

响应式化的入口位于 src/core/instance/init.js 的 initState 中:

// src/core/instance/state.js

export function initState(vm: Component) {
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)              // 初始化props
  if (opts.methods) initMethods(vm, opts.methods)        // 初始化methods
  if (opts.data) initData(vm)                            // 初始化data
  if (opts.computed) initComputed(vm, opts.computed)     // 初始化computed
  if (opts.watch) initWatch(vm, opts.watch)              // 初始化watch
  }
}
로그인 후 복사

它非常规律的定义了几个方法来初始化 propsmethodsdatacomputedwathcer,这里看一下 initData 方法,来窥一豹

// src/core/instance/state.js

function initData(vm: Component) {
  let data = vm.$options.data
  data = vm._data = typeof data === 'function'
                    ? getData(data, vm)
                    : data || {}
  observe(data, true /* asRootData */)             // 给data做响应式处理
}
로그인 후 복사

首先判断了下 data 是不是函数,是则取返回值不是则取自身,之后有一个 observe 方法对 data 进行处理,这个方法尝试给创建一个Observer实例 __ob__,如果成功创建则返回新的Observer实例,如果已有Observer实例则返回现有的Observer实例

2.2 Observer/defineReactive

// src/core/observer/index.js

export function observe (value: any, asRootData: ?boolean): Observer | void {
  let ob: Observer | void
  ob = new Observer(value)
  return ob
}
로그인 후 복사

这个方法主要用 data 作为参数去实例化一个 Observer 对象实例,Observer 是一个 Class,用于依赖收集和 notify 更新,Observer 的构造函数使用 defineReactive 方法给对象的键响应式化,给对象的属性递归添加 getter/setter ,当data被取值的时候触发 getter 并搜集依赖,当被修改值的时候先触发 getter 再触发 setter 并派发更新

// src/core/observer/index.js

export class Observer {
  value: any;
  dep: Dep;

  constructor (value: any) {
    value: any;
    this.dep = new Dep()
    def(value, '__ob__', this)    // def方法保证不可枚举
    this.walk(value)
  }

  // 遍历对象的每一个属性并将它们转换为getter/setter
  walk (obj: Object) {
    const keys = Object.keys(obj)
    for (let i = 0; i <p><code>getter</code> 的时候进行依赖的收集,注意这里,只有在 <code>Dep.target</code> 中有值的时候才会进行依赖收集,这个 <code>Dep.target</code> 是在Watcher实例的 <code>get</code> 方法调用的时候 <code>pushTarget</code> 会把当前取值的watcher推入 <code>Dep.target</code>,原先的watcher压栈到 <code>targetStack</code> 栈中,当前取值的watcher取值结束后出栈并把原先的watcher值赋给 <code>Dep.target</code>,<code>cleanupDeps</code> 最后把新的 <code>newDeps</code> 里已经没有的watcher清空,以防止视图上已经不需要的无用watcher触发</p><p><code>setter</code> 的时候首先 <code>getter</code>,并且比对旧值没有变化则return,如果发生变更,则dep通知所有subs中存放的依赖本数据的Watcher实例 <code>update</code> 进行更新,这里 <code>update</code> 中会 <code>queueWatcher( )</code> 异步推送到调度者观察者队列 <code>queue</code> 中,在nextTick时 <code>flushSchedulerQueue( )</code> 把队列中的watcher取出来执行 <code>watcher.run</code> 且执行相关钩子函数</p><h3 id="Dep">2.3 Dep</h3><p>上面多次提到了一个关键词 <code>Dep</code></p><h2 id="반응형-시스템"> 1. 반응형 시스템</h2> <strong>공식 웹사이트의 소개를 통해 Vue.js가 뷰 변경에 관심이 없지만 데이터를 통해 뷰 업데이트를 구동하므로 상태 관리가 매우 간단하다는 것을 알 수 있습니다. 달성? 공식 홈페이지에서 사진 훔치기</strong><img src="/static/imghw/default1.png" data-src="https://img.php.cn//upload/image/780/349/668/1531105929801901.png" class="lazy" title="1531105929801901. png" alt="Vue 소스 코드의 종속성 수집 원칙">#🎜🎜##🎜🎜#각 구성 요소 인스턴스에는 해당 <code>Watcher</code> 인스턴스 개체가 있으며, 속성은 종속성으로 기록됩니다. , 나중에 종속성의 <code>setter</code>가 호출되면 <code>watcher</code>에 다시 계산하라는 알림이 전달되어 관련 구성 요소가 업데이트됩니다. #🎜🎜##🎜🎜#여기에는 세 가지 중요한 개념이 있습니다: <code>Observe</code>, <code>Dep</code>, <code>Watcher</code>는 <code>에 있습니다. src/core/observer/index.js</code>, <code>src/core/observer/dep.js</code>, <code>src/core/observer/watcher.js</code>#🎜🎜 #
로그인 후 복사
  • #🎜🎜#Observe 클래스는 주로 종속성 수집을 위해 반응형 개체의 속성에 getter/setter를 추가합니다. 업데이트 전달 #🎜🎜#
  • #🎜🎜#Dep 클래스는 현재 반응형 객체의 종속성을 수집하는 데 사용됩니다 #🎜🎜#
  • # 🎜🎜#Watcher 클래스는 관찰자이며 해당 인스턴스는 렌더링 관찰자, 계산된 속성 관찰자 및 리스너 관찰자의 세 가지 유형으로 나뉩니다. #🎜🎜#

2. 코드 구현

2.1 initState

#🎜🎜#반응형 입구는 src/core/instance/init.js의 initState에 있습니다: #🎜🎜#
// src/core/observer/dep.js

let uid = 0            // Dep实例的id,为了方便去重

export default class Dep {
  static target: ?Watcher           // 当前是谁在进行依赖的收集
  id: number
  subs: Array<watcher>              // 观察者集合
  
  constructor() {
    this.id = uid++                             // Dep实例的id,为了方便去重
    this.subs = []                              // 存储收集器中需要通知的Watcher
  }

  addSub(sub: Watcher) { ... }  /* 添加一个观察者对象 */
  removeSub(sub: Watcher) { ... }  /* 移除一个观察者对象 */
  depend() { ... }  /* 依赖收集,当存在Dep.target的时候把自己添加观察者的依赖中 */
  notify() { ... }  /* 通知所有订阅者 */
}

const targetStack = []           // watcher栈

export function pushTarget(_target: ?Watcher) { ... }  /* 将watcher观察者实例设置给Dep.target,用以依赖收集。同时将该实例存入target栈中 */
export function popTarget() { ... }  /* 将观察者实例从target栈中取出并设置给Dep.target */</watcher>
로그인 후 복사
로그인 후 복사
#🎜🎜#it props, methods, data, computed, 그리고 wathcer, initData 메서드를 살펴보고 살짝 살펴보겠습니다#🎜🎜#
// src/core/observer/watcher.js

/* 一个解析表达式,进行依赖收集的观察者,同时在表达式数据变更时触发回调函数。它被用于$watch api以及指令 */
export default class Watcher {
  constructor(
    vm: Component,
    expOrFn: string | Function,
    cb: Function,
    options?: ?Object,
    isRenderWatcher?: boolean      // 是否是渲染watcher的标志位
  ) {
    this.getter = expOrFn                // 在get方法中执行
    if (this.computed) {                   // 是否是 计算属性
      this.value = undefined
      this.dep = new Dep()                 // 计算属性创建过程中并未求值
    } else {                               // 不是计算属性会立刻求值
      this.value = this.get()
    }
  }

  /* 获得getter的值并且重新进行依赖收集 */
  get() {
    pushTarget(this)                // 设置Dep.target = this
    let value
    value = this.getter.call(vm, vm)
    popTarget()                      // 将观察者实例从target栈中取出并设置给Dep.target
    this.cleanupDeps()
    return value
  }

  addDep(dep: Dep) { ... }  /* 添加一个依赖关系到Deps集合中 */
  cleanupDeps() { ... }  /* 清理newDeps里没有的无用watcher依赖 */
  update() { ... }  /* 调度者接口,当依赖发生改变的时候进行回调 */
  run() { ... }  /* 调度者工作接口,将被调度者回调 */
  getAndInvoke(cb: Function) { ... }
  evaluate() { ... }  /* 收集该watcher的所有deps依赖 */
  depend() { ... }  /* 收集该watcher的所有deps依赖,只有计算属性使用 */
  teardown() { ... }  /* 将自身从所有依赖收集订阅列表删除 */
}
로그인 후 복사
로그인 후 복사
#🎜🎜#먼저 데이터가 함수인지 확인하고, 그렇다면 반환 값을 취하고, 그렇지 않으면 data를 처리하는 observe 메서드가 있습니다. 이 메서드는 Observer 인스턴스 를 생성하려고 시도합니다. __ob__, 성공적으로 생성되면 새 Observer 인스턴스를 반환합니다. Observer 인스턴스가 있으면 기존 Observer 인스턴스 #🎜🎜#

2.2 Observer/defineReactive

rrreee#🎜🎜를 반환합니다. #이 메소드는 주로 data를 매개변수로 사용하여 Observer 객체 인스턴스를 인스턴스화합니다. Observer는 종속성 수집 및 notify 업데이트에 사용되는 클래스입니다. code>defineReactive 메소드를 사용하여 객체의 키 형식을 반응적으로 지정합니다. 속성은 getter/setter를 사용하여 반복적으로 추가되며, getter가 트리거되고 종속성이 수집됩니다. . 값이 수정되면 getter가 먼저 트리거됩니다. setter가 다시 트리거되고 업데이트가 전송되면 #🎜🎜#rrreee#🎜🎜#getter code>에 종속성이 수집됩니다. 여기서는 <code>Dep.target만 종속성 수집이 code>에 값이 있는 경우에만 수행된다는 점에 유의하세요. Watcher 인스턴스의 get 메서드가 호출됩니다. pushTarget은 감시자의 현재 값을 Dep.target에 푸시하고, 원래 감시자를 targetStack 스택, 그리고 값이 완료된 후 감시자의 현재 값을 스택에서 팝합니다. 감시자 값은 Dep.target, cleanupDeps 그리고 마지막으로 더 이상 새 <code>newDeps에 없는 감시자는 보기에서 더 이상 필요하지 않도록 지워집니다. 쓸모 없는 감시자가 #🎜🎜##🎜🎜#setter, 먼저 getter를 수행하고, 이전 값과 비교하여 변경 사항이 없으면 반환합니다. 변경 사항이 있으면 dep는 모든 Watcher 인스턴스 update에 알립니다. > 이 데이터에 의존하는 하위 항목에 저장된 updatequeueWatcher( )에 의해 스케줄러 관찰자 대기열에 비동기적으로 푸시됩니다. , nextTick에서 flushSchedulerQueue( )는 대기열에 있는 감시자를 꺼내고 watcher.run을 실행하고 관련 후크 함수를 실행합니다#🎜🎜#

2.3 Dep

#🎜🎜#키워드 Dep는 위에서 여러 번 언급한 바 있으며 종속성 수집을 위한 컨테이너이거나 #🎜🎜#Dependency Collector#🎜🎜라고도 합니다. #, 그는 어떤 Watchers를 기록합니다. 자신의 변경 사항에 의존하거나 자신의 변경 사항을 구독하는 Watchers는 다음 네티즌의 인용문입니다. #🎜🎜#
@liuhongyi0101 :简单点说就是引用计数 ,谁借了我的钱,我就把那个人记下来,以后我的钱少了 我就通知他们说我没钱了

而把借钱的人记下来的小本本就是这里 Dep 实例里的subs

// src/core/observer/dep.js

let uid = 0            // Dep实例的id,为了方便去重

export default class Dep {
  static target: ?Watcher           // 当前是谁在进行依赖的收集
  id: number
  subs: Array<watcher>              // 观察者集合
  
  constructor() {
    this.id = uid++                             // Dep实例的id,为了方便去重
    this.subs = []                              // 存储收集器中需要通知的Watcher
  }

  addSub(sub: Watcher) { ... }  /* 添加一个观察者对象 */
  removeSub(sub: Watcher) { ... }  /* 移除一个观察者对象 */
  depend() { ... }  /* 依赖收集,当存在Dep.target的时候把自己添加观察者的依赖中 */
  notify() { ... }  /* 通知所有订阅者 */
}

const targetStack = []           // watcher栈

export function pushTarget(_target: ?Watcher) { ... }  /* 将watcher观察者实例设置给Dep.target,用以依赖收集。同时将该实例存入target栈中 */
export function popTarget() { ... }  /* 将观察者实例从target栈中取出并设置给Dep.target */</watcher>
로그인 후 복사
로그인 후 복사

这里 Dep 的实例中的 subs 搜集的依赖就是 watcher 了,它是 Watcher 的实例,将来用来通知更新

2.4 Watcher

// src/core/observer/watcher.js

/* 一个解析表达式,进行依赖收集的观察者,同时在表达式数据变更时触发回调函数。它被用于$watch api以及指令 */
export default class Watcher {
  constructor(
    vm: Component,
    expOrFn: string | Function,
    cb: Function,
    options?: ?Object,
    isRenderWatcher?: boolean      // 是否是渲染watcher的标志位
  ) {
    this.getter = expOrFn                // 在get方法中执行
    if (this.computed) {                   // 是否是 计算属性
      this.value = undefined
      this.dep = new Dep()                 // 计算属性创建过程中并未求值
    } else {                               // 不是计算属性会立刻求值
      this.value = this.get()
    }
  }

  /* 获得getter的值并且重新进行依赖收集 */
  get() {
    pushTarget(this)                // 设置Dep.target = this
    let value
    value = this.getter.call(vm, vm)
    popTarget()                      // 将观察者实例从target栈中取出并设置给Dep.target
    this.cleanupDeps()
    return value
  }

  addDep(dep: Dep) { ... }  /* 添加一个依赖关系到Deps集合中 */
  cleanupDeps() { ... }  /* 清理newDeps里没有的无用watcher依赖 */
  update() { ... }  /* 调度者接口,当依赖发生改变的时候进行回调 */
  run() { ... }  /* 调度者工作接口,将被调度者回调 */
  getAndInvoke(cb: Function) { ... }
  evaluate() { ... }  /* 收集该watcher的所有deps依赖 */
  depend() { ... }  /* 收集该watcher的所有deps依赖,只有计算属性使用 */
  teardown() { ... }  /* 将自身从所有依赖收集订阅列表删除 */
}
로그인 후 복사
로그인 후 복사

get 方法中执行的 getter 就是在一开始new渲染watcher时传入的 updateComponent = () => { vm._update(vm._render(), hydrating) },这个方法首先 vm._render() 生成渲染VNode树,在这个过程中完成对当前Vue实例 vm 上的数据访问,触发相应一众响应式对象的 getter,然后 vm._update()patch

注意这里的 get 方法最后执行了 getAndInvoke,这个方法首先遍历watcher中存的 deps,移除 newDep 中已经没有的订阅,然后 depIds = newDepIds; deps = newDeps ,把 newDepIdsnewDeps 清空。每次添加完新的订阅后移除旧的已经不需要的订阅,这样在某些情况,比如 v-if 已不需要的模板依赖的数据发生变化时就不会通知watcher去 update

2.5 小结

整个收集的流程大约是这样的,可以对照着上面的流程看一下

Vue 소스 코드의 종속성 수집 원칙

watcher 有下面几种使用场景:

  • render watcher 渲染 watcher,渲染视图用的 watcher

  • computed watcher 计算属性 watcher,因为计算属性即依赖别人也被人依赖,因此也会持有一个 Dep 实例

  • watch watcher 侦听器 watcher

只要会被别的观察者 (watchers) 依赖,比如data、data的属性、计算属性、props,就会在闭包里生成一个 Dep 的实例 dep 并在被调用 getter 的时候 dep.depend 收集它被谁依赖了,并把被依赖的watcher存放到自己的subs中 this.subs.push(sub),以便在自身改变的时候通知 notify 存放在 dep.subs 数组中依赖自己的 watchers 自己改变了,请及时 update ~

只要依赖别的响应式化对象的对象,都会生成一个观察者 watcher ,用来统计这个 watcher 依赖了哪些响应式对象,在这个 watcher 求值前把当前 watcher 设置到全局 Dep.target,并在自己依赖的响应式对象发生改变的时候及时 update

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

jQuery源码之Callbacks的学习

浏览器与NodeJS的EventLoop异同以及部分机制

위 내용은 Vue 소스 코드의 종속성 수집 원칙의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

vite가 .env 파일을 구문 분석하는 방법에 대한 심층 토론 vite가 .env 파일을 구문 분석하는 방법에 대한 심층 토론 Jan 24, 2023 am 05:30 AM

Vue 프레임워크를 사용하여 프런트엔드 프로젝트를 개발할 때 배포 시 여러 환경을 배포하게 되는데, 개발 환경, 테스트 환경, 온라인 환경에서 호출되는 인터페이스 도메인 이름이 다른 경우가 많습니다. 어떻게 구별할 수 있나요? 그것은 환경 변수와 패턴을 사용하는 것입니다.

Vue 프로젝트에 Ace 코드 편집기를 통합하는 방법에 대한 자세한 그래픽 설명 Vue 프로젝트에 Ace 코드 편집기를 통합하는 방법에 대한 자세한 그래픽 설명 Apr 24, 2023 am 10:52 AM

Ace는 JavaScript로 작성된 내장형 코드 편집기입니다. Sublime, Vim 및 TextMate와 같은 기본 편집기의 기능 및 성능과 일치합니다. 모든 웹페이지와 JavaScript 애플리케이션에 쉽게 삽입할 수 있습니다. Ace는 Cloud9 IDE의 메인 편집자로 유지되며 Mozilla Skywriter(Bespin) 프로젝트의 후속 버전입니다.

vue에서 구성 요소화와 모듈화의 차이점은 무엇입니까 vue에서 구성 요소화와 모듈화의 차이점은 무엇입니까 Dec 15, 2022 pm 12:54 PM

구성요소화와 모듈화의 차이점: 모듈화는 코드 논리의 관점에서 구분되며, 코드 계층 개발을 용이하게 하고 각 기능 모듈의 기능이 일관되게 유지되도록 합니다. 컴포넌트화는 UI 인터페이스 관점에서 계획하는 것으로 프런트엔드의 컴포넌트화는 UI 컴포넌트의 재사용을 용이하게 합니다.

Vue3에서 단위 테스트를 작성하는 방법 살펴보기 Vue3에서 단위 테스트를 작성하는 방법 살펴보기 Apr 25, 2023 pm 07:41 PM

Vue.js는 오늘날 프런트엔드 개발에서 매우 인기 있는 프레임워크가 되었습니다. Vue.js가 계속 발전함에 따라 단위 테스트는 점점 더 중요해지고 있습니다. 오늘은 Vue.js 3에서 단위 테스트를 작성하는 방법을 살펴보고 몇 가지 모범 사례와 일반적인 문제 및 솔루션을 제공하겠습니다.

vue3의 반응성()에 대해 자세히 이야기해 봅시다. vue3의 반응성()에 대해 자세히 이야기해 봅시다. Jan 06, 2023 pm 09:21 PM

서문: vue3 개발에서 반응형은 반응형 데이터를 구현하는 방법을 제공합니다. 일상적인 개발에서 자주 사용되는 API입니다. 이 기사에서 저자는 내부 작동 메커니즘을 탐구합니다.

Vue의 JSX 구문과 템플릿 구문의 간단한 비교(장단점 분석) Vue의 JSX 구문과 템플릿 구문의 간단한 비교(장단점 분석) Mar 23, 2023 pm 07:53 PM

Vue.js에서 개발자는 JSX 구문과 템플릿 구문이라는 두 가지 다른 구문을 사용하여 사용자 인터페이스를 만들 수 있습니다. 두 구문 모두 장점과 단점이 있습니다. 차이점, 장점 및 단점을 논의해 보겠습니다.

Vue3 동적 구성 요소에서 예외를 처리하는 방법에 대한 간략한 분석 Vue3 동적 구성 요소에서 예외를 처리하는 방법에 대한 간략한 분석 Dec 02, 2022 pm 09:11 PM

Vue3 동적 구성 요소에서 예외를 처리하는 방법은 무엇입니까? 다음 기사에서는 Vue3 동적 구성 요소 예외 처리 방법에 대해 설명합니다. 이것이 모든 사람에게 도움이 되기를 바랍니다.

vue가 파일 분할 업로드를 구현하는 방법에 대한 간략한 분석 vue가 파일 분할 업로드를 구현하는 방법에 대한 간략한 분석 Mar 24, 2023 pm 07:40 PM

실제 개발 프로젝트 프로세스에서는 상대적으로 큰 파일을 업로드해야 하는 경우가 있는데, 그러면 업로드가 상대적으로 느려지므로 백그라운드에서 파일 조각을 업로드하려면 매우 간단합니다. 기가바이트 파일 스트림이 여러 개의 작은 파일 스트림으로 절단된 다음 인터페이스는 작은 파일 스트림을 각각 전달하도록 요청됩니다.

See all articles