I have done many projects on VueJS, and I realize that there are many tricks implemented in VueJS that if I shook hands right from the beginning of the project, everything would be better later. If not later on, I will have to spend more time sitting refactor there. And go to the main content of the parts I want to share only, note that this article is for those of you who already have the basic knowledge of Vue, and those who are new to Vue, I think bookmarking is not necessary to read this article.
Use Vuex before it’s too late
If you are building a medium to large project then I think there will be a lot of resources to manage, not to mention that I will have to work with different data between different components, I think it will be quite is difficult and confusing and somehow your code gets duplicated if you don’t manage it well. Sometimes it also causes bugs because of the dependency between components too much.
So Evan You created Vuex to accompany Vue. Vuex is not needed for a small project or working on little data. But for medium and above projects it is really necessary. Since using Vuex projects, I feel less headache
Understand the component a bit
Static Components
From Vue 2 we can use so-called static components. Its advantages are fast and light. These components usually have no state or internal data and are usually displayed only once. This allows such functional components to be extremely fast. To use this feature, you can use v-once in the cards you want to display once.
1 2 3 | // Example <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> span</span> <span class="token attr-name">v-once</span> <span class="token punctuation">></span></span> This will never change <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> span</span> <span class="token punctuation">></span></span> |
Potential Confusion
At beginner vue themselves known within one component alone will define the attributes in the data
, the properties calculated in computed
and methods in the methods
and times to call these things we only need this
. Sometimes I wonder if sometimes it gets confused like this instead of this.methods
or this.property
is not this.type.thing
( this.methods.methodName
)
Actually everything I define in that component is simply at the Định nghĩa
level and actually things that run in those attribute methods Vue reassemble the data
, methods
, computed
, etc. ….. v in another component already. And for convenience, it all maps to the component’s root
Rerender Component
Occasionally we will need to re-render our component: -? And think about how you would do it a little bit? I will list the ways for you to do that
- Reload page =)))))) (Worst way)
- Using Hack v-if (The worst way)
- Using ForceUpdate (Good way)
- Change the value of the key (The best way)
Reload page ??
Ok this means you need to restart your computer every time you want to close an application. I personally think it will work =)))) However it’s a pretty bad solution. There’s really not much to say about this. Do not do that. No No
HACK V-IF
The Vue that comes with v-if
will display the component when it’s true
. If it is false
, the element will not exist at all in the DOM. The following example is how to use v-if
to rerender.
1 2 3 4 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> my-component</span> <span class="token attr-name">v-if</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> isRender <span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> |
And in the script we will have nextTick =))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token operator"><</span> script <span class="token operator">></span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token function">data</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> isRender <span class="token punctuation">:</span> <span class="token boolean">true</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> methods <span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token function">forceRerender</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xóa my-component khỏi DOM</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> isRender <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> <span class="token function">$nextTick</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 comment">// Add my-component lại</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> isRender <span class="token operator">=</span> <span class="token boolean">true</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 punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token operator"><</span> <span class="token operator">/</span> script <span class="token operator">></span> |
And what happens in the code above?
- The first isRender is set to
true
, somy-component
is displayed - When I call forceRerender, I immediately set
isRender
to false my-component
is now removed on the DOM becausev-if
is nowfalse
- When running to nextTick (you do not know about nextTick can refer to this article Vue Nextick ), I will reset to
true
- This time
v-if
has a value of true so it will remy-component
rendermy-component
There are two important things I want you to know about
- Firstly, that is we have to wait for nextTick
- Secondly, Vue will create a whole new component when we render it again the second time. Vue will destroy the first component and create a new one ???? What does that mean? Oh right =))) That means
my-component
will go through all of its life cycles. Actually, in my opinion this is not a good solution or I call itHACK V-IF
because this way we are hacking around what Vue wants us to do. Sohãy làm những gì vue muốn chúng ta làm
Force Update
This is one of the two best ways to solve this problem, and both are recommended by Vue =)))))) Vue will usually update itself on Vue if there is a change, and when we call forceUpdate
we can make it update again
…
Vue automatically updated when everything changed then why do we force Update ???? The reason is because sometimes the reactivity system of vue it does not work offline =)))) Better understand you can read This article So if you need to update the component using this method will be better than the above 2 ways = )))) Note: forceUpdate it only updates the view only: -? See more about it
KEY – Best solution
This is the best of all. I will assign a key
attribute to a component so Vue knows that a component is tied to a specific piece of data. If the key
stays the same, it doesn’t change the component, but if the key
changes, Vue knows that it will delete the old component and create a new component. =))) Exactly what we need But first we need to talk a little bit about Key and why are we using it
I assume we use v-for
to load an array of objects. If we sort that array or fix it in any way, we need to rerender that list. But you don’t want to re-render everything related to that list, but just the things that change
In order for Vue to know what has changed and what has not, I will insert the key
attribute using the index
1 2 3 4 5 6 | <span class="token keyword">const</span> people <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">'Nguyen Van A'</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">22</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">'Van B'</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">44</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">'Van C'</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">33</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> |
And we use v-for in combination with the key index
1 2 3 4 5 6 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> ul</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> li</span> <span class="token attr-name">v-for</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> (person, index) in people <span class="token punctuation">"</span></span> <span class="token attr-name">:key</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> index <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> {{ person.name }} - {{ index }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> li</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> ul</span> <span class="token punctuation">></span></span> |
1 2 3 4 5 | // Outputs Nguyen Van A - 0 Van B - 1 Van C - 2 |
Now for example, I will delete Van B
output will be
1 2 3 4 | // Outputs Nguyen Van A - 0 Van C - 1 |
Van C
‘s index has been changed, although Van C
is still the same object, but the problem is that Van C
‘s index has changed and will be re-rendered. So here we need a unique id
that’s like this
1 2 3 4 5 6 | <span class="token keyword">const</span> people <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> <span class="token string">'unique-1'</span> <span class="token punctuation">,</span> name <span class="token punctuation">:</span> <span class="token string">'Nguyen Van A'</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">22</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> <span class="token string">'unique-2'</span> <span class="token punctuation">,</span> name <span class="token punctuation">:</span> <span class="token string">'Van B'</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">44</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> <span class="token string">'unique-3'</span> <span class="token punctuation">,</span> name <span class="token punctuation">:</span> <span class="token string">'Van C'</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">33</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> |
In the example using the above index when we delete Van B
Vue will delete Van B
, Van C
and re-render another Van C
When we use the unique id now Vue knows that it can be between Nguyen Van A
and Van C
just delete Van B
It is very optimized right? Finally, it is to use the key
to rerender component
1 2 3 4 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> my-component</span> <span class="token attr-name">:key</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> idCom <span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token function">data</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> idCom <span class="token punctuation">:</span> <span class="token number">0</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> methods <span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token function">forceRerender</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> idCom <span class="token operator">+=</span> <span class="token number">1</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
OK Done =)))) Above is the best way, right
Multiple Root Node
I guess you will sometimes encounter an error called Đéo tìm thấy node cha
=))) when compile Like this
1 2 3 4 5 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Node 1 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Node 2 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> |
And we will fix by adding a div
tag
1 2 3 4 5 6 7 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Node 1 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Node 2 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> |
If it does not matter, it is okay but in many cases I should not have a root node or na I need many root nodes =)) (like css, table) and so on. There is a solution: -? (Vue 3 seems to be ok then skip to Vue 2 then stick huhu) Like React will have React Fragment
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">class</span> <span class="token class-name">Columns</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Ok so VUE What do we got vue-fragment =)))
1 2 3 4 | <span class="token comment">// Use</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Plugin <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"vue-fragments"</span> <span class="token punctuation">;</span> Vue <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> Plugin <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
1 2 3 4 5 6 7 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> v-fragment</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Fragment 1 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Fragment 2 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> v-fragment</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> |
Validate data easily with Vuelidate
There have been projects that I work on, which only work with forms, and validating data is extremely necessary (Both server and client). And there is a pretty good library that I really like is Vuelidate. This is very recommended for me because if I validate by hand at the time I see the form & the logic is very simple. )))) You can refer to the sample validate here
Use events rather than callbacks
When we work with father and son components, there will be places that need data interaction between the father and the child and vice versa. There are two common ways we do it
- Use callback functions in props
- Using events Here I do not compare the differences between the 2 guys but I personally prefer using events over 2 reasons
- It is a clear separation between “what the child component receives” and “what the child component sends to the parent component”.
- I see standard in the examples and Vue documents, most of them use events to interact from child components to the father
An example of using Callbacks and Events is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token comment">// child-component.vue</span> <span class="token comment">// Callbacks</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> props <span class="token punctuation">:</span> <span class="token punctuation">[</span> <span class="token string">'onActionSubmit'</span> <span class="token punctuation">,</span> <span class="token operator">...</span> <span class="token punctuation">]</span> <span class="token function">methods</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleAction</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token keyword">typeof</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> onActionSubmit <span class="token operator">===</span> <span class="token string">'function'</span> <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">onActionSubmit</span> <span class="token punctuation">(</span> data <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 punctuation">}</span> |
1 2 3 | <span class="token comment">// parent-component.vue</span> <span class="token operator"><</span> child <span class="token operator">-</span> component <span class="token punctuation">:</span> onActionSubmit <span class="token operator">=</span> <span class="token string">"actionSubmit"</span> <span class="token operator">/</span> <span class="token operator">></span> |
Above is the direction to use callbacks and below is the use of events
1 2 3 4 5 6 7 8 9 | <span class="token comment">// child-component.vue</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token function">methods</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleAction</span> <span class="token punctuation">(</span> <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">$emit</span> <span class="token punctuation">(</span> <span class="token string">'action-submit'</span> <span class="token punctuation">,</span> data <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> |
1 2 | <span class="token operator"><</span> child <span class="token operator">-</span> component @action <span class="token operator">-</span> submit <span class="token operator">=</span> <span class="token string">"actionSubmit"</span> <span class="token operator">/</span> <span class="token operator">></span> |
Reuse transitions
Transitions in vue is something that I really like because of its simple use and nice effects The simplest way to use can be mentioned in the following example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">id</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> app <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name"><span class="token namespace">v-on:</span> click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> show = !show <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Toggle <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> transition</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> fade <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> p</span> <span class="token attr-name">v-if</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> show <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> hello <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> p</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> transition</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">"App"</span> <span class="token punctuation">,</span> <span class="token function">data</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> show <span class="token punctuation">:</span> <span class="token boolean">true</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> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> style</span> <span class="token punctuation">></span></span> <span class="token style language-css"> <span class="token selector">.fade-enter-active, .fade-leave-active</span> <span class="token punctuation">{</span> <span class="token property">transition</span> <span class="token punctuation">:</span> opacity 0.3s <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.fade-enter, .fade-leave-to</span> <span class="token punctuation">{</span> <span class="token property">opacity</span> <span class="token punctuation">:</span> 0 <span class="token punctuation">;</span> <span class="token punctuation">}</span> </span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> style</span> <span class="token punctuation">></span></span> |
However, if I write like this, then I’m hard to reuse, maybe I will have to write everywhere like that, it’s very tiring. Here I will encapsulated this transition into a component like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> transition</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> fade <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> slot</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> slot</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> transition</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> </span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> style</span> <span class="token punctuation">></span></span> <span class="token style language-css"> <span class="token selector">.fade-enter-active, .fade-leave-active</span> <span class="token punctuation">{</span> <span class="token property">transition</span> <span class="token punctuation">:</span> opacity 0.3s <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.fade-enter, .fade-leave-to</span> <span class="token punctuation">{</span> <span class="token property">opacity</span> <span class="token punctuation">:</span> 0 <span class="token punctuation">;</span> <span class="token punctuation">}</span> </span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> style</span> <span class="token punctuation">></span></span> |
And on the app, I just call like this
1 2 3 4 5 6 7 8 9 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">id</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> app <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name"><span class="token namespace">v-on:</span> click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> show = !show <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Toggle transition <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> fade-transition</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">v-if</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> show <span class="token punctuation">"</span></span> <span class="token attr-name">class</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> box <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> fade-transition</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> |
It looks better then, but what if I want to use another mode or I want to bind property then why are all the other guys affected ??? The answer is no =)) that we will pass on the calling party to the components. In the transition component we just need to add $attrs
or $listeners
to solve the problem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> transition</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> fade <span class="token punctuation">"</span></span> <span class="token attr-name">v-bind</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> $attrs <span class="token punctuation">"</span></span> <span class="token attr-name">v-on</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> $listeners <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> slot</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> slot</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> transition</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> </span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> style</span> <span class="token punctuation">></span></span> <span class="token style language-css"> <span class="token selector">.fade-enter-active, .fade-leave-active</span> <span class="token punctuation">{</span> <span class="token property">transition</span> <span class="token punctuation">:</span> opacity 0.3s <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.fade-enter, .fade-leave-to</span> <span class="token punctuation">{</span> <span class="token property">opacity</span> <span class="token punctuation">:</span> 0 <span class="token punctuation">;</span> <span class="token punctuation">}</span> </span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> style</span> <span class="token punctuation">></span></span> |
Outside the app will call
1 2 3 4 5 6 7 8 9 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">id</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> app <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name"><span class="token namespace">v-on:</span> click</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> show = !show <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Toggle transition <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> fade-transition</span> <span class="token attr-name">mode</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> out-in <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token attr-name">v-if</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> show <span class="token punctuation">"</span></span> <span class="token attr-name">class</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> box <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> fade-transition</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> |
Dynamic loading of routes
For those of you who often work with Vue, it is not strange that this vue-router This guy helps me route the links to each component. For those who use VUE CLI to create projects, it often asks if you want to install vue-router.
Problems of routes.js ???
I also do some vue-related projects and use vue-routers, I have the problem that in the routes file I define each route 1, this route points to this component, …. Gradually the file routes So it started to grow. You can understand that an average project has 5 6 resources. For every resource, we just have to take 1 CRUD Routes for it. That’s not to say the routes are not crud. And this problem made me really inhibited and took a lot of time =))) to find a certain route and it was very confusing.
Solution
From the above problem I am craving a pretty good solution and I will share it with you. First we want to load the routes it automatically means that our directory structure must follow a certain standard. Since a route consists of paths, components, and dynamic params, your directory should also be set according to the standard so that the logic for loading routes is simpler and also helps to make the project look cleaner.
Usually I know there will be 2 types of directory division
Functionality
- In this manner, the struct will include a component function directory (containing all file components), a functional directory of the router (containing all router files according to resources), a directory containing vuex (containing the store api of resources)
Feature type – Feature
- This type, we consider each resource will be a feature and I will put in 1 resource directory, this directory will include from Components, Route, Store Vuex
In this article I will demo load routes according to the directory structure feature, the structure will look like the following
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /src | ---/modules | ---/user | ---User.vue ---routes.js ---store.js /event | ---Event.vue ---routes.js ---store.js /job | ---Job.vue ---routes.js ---store.js |
And this is how I implemented it in the routes.js file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span> <span class="token keyword">import</span> Router <span class="token keyword">from</span> <span class="token string">'vue-router'</span> <span class="token keyword">import</span> Home <span class="token keyword">from</span> <span class="token string">'@/components/Home'</span> <span class="token keyword">import</span> Auth <span class="token keyword">from</span> <span class="token string">'@/components/Auth'</span> <span class="token punctuation">;</span> Vue <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> Router <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Other routes</span> <span class="token keyword">let</span> routes <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> path <span class="token punctuation">:</span> <span class="token string">'/'</span> <span class="token punctuation">,</span> name <span class="token punctuation">:</span> <span class="token string">'home'</span> <span class="token punctuation">,</span> component <span class="token punctuation">:</span> Home <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> path <span class="token punctuation">:</span> <span class="token string">'/login'</span> <span class="token punctuation">,</span> name <span class="token punctuation">:</span> <span class="token string">'auth'</span> <span class="token punctuation">,</span> component <span class="token punctuation">:</span> Auth <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">// Import toàn bộ file routes</span> <span class="token keyword">function</span> <span class="token function">loadRoutes</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> context <span class="token operator">=</span> require <span class="token punctuation">.</span> <span class="token function">context</span> <span class="token punctuation">(</span> <span class="token string">'@/modules'</span> <span class="token punctuation">,</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> <span class="token regex">/routes.js$/i</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> context <span class="token punctuation">.</span> <span class="token function">keys</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token comment">// import module</span> <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> m <span class="token operator">=></span> m <span class="token punctuation">.</span> <span class="token keyword">default</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// hàm load Routes trên sẽ trả về cho chúng ta 1 mảng resources routes và mình sẽ lặp mảng này và push vào mảng routes </span> <span class="token keyword">const</span> resourceRoutes <span class="token operator">=</span> <span class="token function">loadRoutes</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> resourceRoutes <span class="token punctuation">.</span> <span class="token function">forEach</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> route <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> routes <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> route <span class="token punctuation">[</span> <span class="token number">0</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 punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">new</span> <span class="token class-name">Router</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> mode <span class="token punctuation">:</span> <span class="token string">'history'</span> <span class="token punctuation">,</span> routes <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
It’s been a long time and write to see you in P2, guys