Skip to content

Latest commit

 

History

History
111 lines (65 loc) · 4.51 KB

en-us.md

File metadata and controls

111 lines (65 loc) · 4.51 KB

Why vue source code difficult to read

  1. Include too many features

The main goal of reading vue source code is understanding the whole picture and some core features such as mvvm and virtual dom. Some features make things complicated, such as keep alive, dynamic component and functional component.

  1. Backward compatibility

Vue source code has a lot of backward compatible code, making it too complicated to understand. For example, Vue2.0 uses defineProperty to implement mvvm for backward compatibility. However, it is much easier to do that with ES6 Proxy.

Write vue from scratch

This project follows Vue3.0 plans. I write a simplest vue step by step to make each commit easy to understand.

Step

For each step, I write test case first, then implement it. (TDD)

Basic

In this part, we implement some basic features.

  1. TDD Environment Setup

  2. Data Proxy

  3. Implement $watch

  4. html element rendering

  5. Support method

  6. Support lifecycle

  7. html element event listener

  8. Implement mvvm

  9. Basic Demo

Running npm run test and then click the DEBUG button in the pop-up browser, you will see the demo.

Mvvm in depth

In this part, we improve mvvm to implement all features in vue2.x. Moreover, we implement "Detection of property addition / deletion" in vue3.0 plan. So, no Vue.$set.

  1. [mvvm]support deep object

  2. [mvvm]Detection of property addition

  3. [mvvm]Detection of property deletion

  4. [mvvm]Support array

  5. mvvm in depth demo

  6. Refactoring and comment

Component

  1. Support props

  2. Component rendering

  3. Component event & action

Computed & watch

  1. Computed

  2. watch

  3. Refactor

  4. $nextTick

  5. Watcher Scheduler

Watcher scheduler solves the problem that changing multiple data triggers rendering multiple times

var cb = jasmine.createSpy('cb');

var vm = new Vue({
  data () {
    return {
      a:1,
      b:2,
    }
  },
  render (h) {
    cb()
    return h('p', null, this.a + this.b)
  }
}).$mount()

expect(cb).toHaveBeenCalledTimes(1)

vm.a = 10
vm.b = 11
setTimeout(_ => {
  expect(cb).toHaveBeenCalledTimes(2) // change 'a' and 'b' only trigger one render
  done()
})

Todo list

  1. Patch

  2. Scoped Slot