Hello everyone, it’s me again. If you have not seen the previous section, I recommend that you read it later. You can watch it right here .
In the previous section, we learned together and also installed Reactivity System. However in this section we just go into the initialization, preparation only, the next part we have just started to apply.
Initially build your own Vue
In this section, I will start to declare and prepare a few things for my minimal Vue.
Prepare the development environment
Install browserify , esmify , tinyify to build bundle.
1 2 |
yarn add browserify esmify tinyify |
Install jest for testing.
1 2 |
yarn global add jest |
Initialize Vue
Folder structure
1 2 3 4 5 6 7 8 9 10 11 12 |
vue-minimal |--tests |--|--data.spec.js |--vue |--|--instance |--|--|--index.js |--|--|--init.js |--|--|--state.js |--|--observer |--|--|--index.js |--|--index.js |
Inside:
- The vue / instance directory will save things related to the Vue instance.
- The vue / observer directory will save any related state observations.
Perform
In this part, I will show you the first steps to prepare for a Vue instance and write unit tests.
I will declare Vue instance, enter options and init for options to be accepted.
1 2 3 4 5 6 7 8 |
<span class="token keyword">import</span> <span class="token punctuation">{</span> initMixin <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./init'</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">Vue</span> <span class="token punctuation">(</span> options <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> <span class="token function">_init</span> <span class="token punctuation">(</span> options <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">initMixin</span> <span class="token punctuation">(</span> Vue <span class="token punctuation">)</span> |
The initMixin function will proceed to prepare prototypes for Vue, such as Vue._init is also a prototype prepared in initMixin.
1 2 3 4 5 6 7 8 9 10 11 |
<span class="token keyword">import</span> <span class="token punctuation">{</span> initState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./state'</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">initMixin</span> <span class="token punctuation">(</span> Vue <span class="token punctuation">)</span> <span class="token punctuation">{</span> Vue <span class="token punctuation">.</span> prototype <span class="token punctuation">.</span> <span class="token function-variable function">_init</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> options <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> vm <span class="token operator">=</span> <span class="token keyword">this</span> vm <span class="token punctuation">.</span> $options <span class="token operator">=</span> options <span class="token function">initState</span> <span class="token punctuation">(</span> vm <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Inside Vue._init , we will proceed with the following steps:
- Save the options for later use.
- Proceed to initializing the state.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="token keyword">import</span> <span class="token punctuation">{</span> defineReactiveData <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'../observer/index'</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">initState</span> <span class="token punctuation">(</span> vm <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> opts <span class="token operator">=</span> vm <span class="token punctuation">.</span> $options <span class="token keyword">if</span> <span class="token punctuation">(</span> opts <span class="token punctuation">.</span> data <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">initData</span> <span class="token punctuation">(</span> vm <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">initData</span> <span class="token punctuation">(</span> vm <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> data <span class="token operator">=</span> vm <span class="token punctuation">.</span> $options <span class="token punctuation">.</span> data vm <span class="token punctuation">.</span> $data <span class="token operator">=</span> data <span class="token function">defineReactiveData</span> <span class="token punctuation">(</span> vm <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
In this section, I will come across a function that was mentioned in the previous section is defineReactiveData . But defineReactiveData this time will not have Dep because we do not need to use, now I just need to ensure the synchronization between vm.foo and vm. $ Data.foo .
In that vm is the instance that when I new Vue and vm. $ Data is the data retrieved from the options that I saved in the initData function.
So now our defineReactiveData will only look like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">defineReactiveData</span> <span class="token punctuation">(</span> vm <span class="token punctuation">)</span> <span class="token punctuation">{</span> Object <span class="token punctuation">.</span> <span class="token function">keys</span> <span class="token punctuation">(</span> vm <span class="token punctuation">.</span> $data <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">forEach</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> key <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">defineProxy</span> <span class="token punctuation">(</span> vm <span class="token punctuation">,</span> key <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">defineProxy</span> <span class="token punctuation">(</span> vm <span class="token punctuation">,</span> key <span class="token punctuation">)</span> <span class="token punctuation">{</span> Object <span class="token punctuation">.</span> <span class="token function">defineProperty</span> <span class="token punctuation">(</span> vm <span class="token punctuation">,</span> key <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token punctuation">:</span> <span class="token keyword">function</span> <span class="token function">reactiveGetter</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> vm <span class="token punctuation">.</span> $data <span class="token punctuation">[</span> key <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">set</span> <span class="token punctuation">:</span> <span class="token keyword">function</span> <span class="token function">reactiveSetter</span> <span class="token punctuation">(</span> _value <span class="token punctuation">)</span> <span class="token punctuation">{</span> vm <span class="token punctuation">.</span> $data <span class="token punctuation">[</span> key <span class="token punctuation">]</span> <span class="token operator">=</span> _value <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
At this point, we have completed the initial step of creating the Vue instance.
Build Vue into bundle
After the code is finished, I have to build it into a bundle to use. You will run the following command to proceed to build our Vue bundle bundle as a module so we can import and use.
1 2 |
browserify --s module vue/index.js -p esmify -p tinyify > dist/vue.js |
Write unit tests for the Vue instance
I usually use Jest to write unit tests, so this time I will also use Jest .
I will only check the following 2:
- The value of vm.foo must be the same as vm. $ Data.foo.
- When vm.foo updates, vm. $ Data.foo must also be updated.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="token keyword">const</span> Vue <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'../dist/vue.min'</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token keyword">default</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token string">'vm.foo should be same with vm.$data.foo'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> vm <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vue</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> data <span class="token punctuation">:</span> <span class="token punctuation">{</span> foo <span class="token punctuation">:</span> <span class="token number">1012</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> vm <span class="token punctuation">.</span> foo <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token number">1012</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token string">'update vm.foo, vm.$data.foo should be update too'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> vm <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vue</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> data <span class="token punctuation">:</span> <span class="token punctuation">{</span> foo <span class="token punctuation">:</span> <span class="token number">1012</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> vm <span class="token punctuation">.</span> foo <span class="token operator">=</span> <span class="token number">1210</span> <span class="token function">expect</span> <span class="token punctuation">(</span> vm <span class="token punctuation">.</span> $data <span class="token punctuation">.</span> foo <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token number">1210</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
To run the test I will use the command
1 2 |
jest |
After running we will get the result as shown below.
After running unit tests, if you get a PASS , you have completed the initial step of creating a Vue instance.
Epilogue
In this part 2, I have instructed you to prepare for your own Vue and write unit tests to check if the Vue instance is working properly.
In the next section, I will continue to talk about VNode, how does VNode render DOM DOM? When the state updates, how will the DOM update too!
Thank you for reading this part 2. I hope it helps you understand Vue.