Introduction of Vue.js

https://github.com/vuejs/vue

Here’s a most basic sample code of Vuejs.

http://codepen.io/cctuan/pen/evgLPX

The flow is simple,

  1. Define a vue component as ‘image-group’ 
    a. declare its html template
    b. declare its properties imgId , which means it’s something from outsider
    c. declare a computed imgUrl value based the props value imgId
    d. embed the computed value inside the template
  2. Declare a vue app
    a. define the target element #main it going to mount
    b. declare its html template
    c. define the basic data that the component holds
    d. embed the data in template with a iterator which lists the data
  3. Push a new data to vue app’s list
    a. push a empty object to the app data list

So what will happen after running above code ?

You can open the the codepen link and see what’s going on, you might notice there are 4 images displaying on the result.

What exactly happen in each code …?

Let’s talk about vue’s lifecycle

https://vuejs.org/v2/guide/instance.html

Actually , it’s quite understandable by the Author’s diagram, but I want to share my observation of his source code. So, let’s look into deeper.

First , I want to talk about the core of Vue.js.

defineReactive

https://github.com/vuejs/vue/blob/d6999c19c4c18d5eedfd3a7741e17b0e34e8a8df/src/core/observer/index.js#L131-L184

Object.defineProperty is an ES5 ‘s feature , which allow developer customize an object’s getter and setter. When vuejs is initializing, and run traverse the component’s props and data with defineReative , so whenever you try to get a value from the the component’s data or props from outside component or internal script, it will run its own getter. And what does its own getter do ?

https://github.com/vuejs/vue/blob/d6999c19c4c18d5eedfd3a7741e17b0e34e8a8df/src/core/observer/index.js#L131-L184

when a computed value(imgUrl) trying to get value from its props(this.imgId), it will call the customized getter , and in vuejs’ source code, the computed value will mount him self as a dependency of its props(imgId) pool .

https://github.com/vuejs/vue/blob/d6999c19c4c18d5eedfd3a7741e17b0e34e8a8df/src/core/observer/index.js#L131-L184

It also happens in component, when we trying to get the value of props/data/computed, the component ‘s render function will also mount itself as a dependency to the pool.

when we give a new value to the component’s props(imgId), it will check all of its dependency pool and trigger update methods and reset the related value or re-render the component.

Ok, so we all understand how the defineReactive function do , but when does it happen during vuejs’ lifecycle.

Created

When we new a Vuejs app or write a vue component in someone’s template, vue will start to intialize itself, what he does is as below…

  1. Declare all initial values and methods beforeCreate
    a. init prototype method https://github.com/vuejs/vue/blob/dev/src/core/instance/index.js
    b. initLifeCyclte/initEvents/initRender …
    https://github.com/vuejs/vue/blob/7de165c99e53e5974108b8e5f5981c0b921d248b/src/core/instance/init.js
  2. Traverse all props and data and put them into defineReactive function
    https://github.com/vuejs/vue/blob/abb966b0b62b5f6077816192b41901a3a2e68b52/src/core/instance/state.js

BeforeMount

The most important function running here is parseHtml and generate render function.
https://github.com/vuejs/vue/blob/135f06d25f993cb9ade35c66a1b0cebdcdf1cede/src/compiler/parser/index.js

It read all the special vue tags and the executing order is as below. It also means the priority.
v-for > v-if > v-once > :key > :ref > :slot > :is/:inline-template > others (:xxx and customDiretive ) > v-on

And then it will transform the html to render function which return a executable string.

Basically the algorithm is based on snabbdom , which claim himself as the fast virtual dom library.

Mounted and Update

After we parse the template to render function , the next step is to run it. In this step, vuejs start to initialize virtual node in memory and execute render to the parent element or the target real dom.

When the render function trying to get the value from props/data/computed , it will its render function as a new dependency of them. As mentioned before , when the prop changes then it trigger re-render, which enter into the beforeUpdate stage.

So, if the component is already mounted, and someone trigger re-render , it will quickly compare the old virtual node and new virtual node by vm.__patch__ , which has a very smart traversing method to compare two virtual node trees .It also benefit from snabbdom ( cycle.js is also using it as core) .

That’s pretty much how a vuejs the first half of vuejs’ lifecycle.