Vuejs là một framework tuyệt vời, nó cho chúng ta khả năng tạo ra những trang web phức tạp nhưng cách làm thì thật đơn giản.
Tuy đã sử dựng Vue khá nhiều nhưng mình vẫn chưa thật sự tận dụng được sự những sức mạnh này của Vue, đôi khi code Vue của mình quá dài, quá phức tạp khiến cho chính mình khi lôi ra đọc lại cũng không thể ngửi được, có những components dài đến 300 dòng code @@
Sau một thời gian nhẫn nhịn cuối cùng cũng chịu tìm hiểu cách refactor lại cho code dễ đọc, bỏ những phần thừa thãi để tăng thêm hiệu năng cho project, dưới đây mà một số cách mà mình sưu tầm được và tự mò ra trong quá trình làm việc với Vue.
Trước hết hãy xem qua ví dụ thực tế mà chúng ta sẽ refactor lại:
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 | <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">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>article-preview<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>rwv-article-meta</span> <span class="token attr-name">:article</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>article<span class="token punctuation">"</span></span> <span class="token attr-name">:isPreview</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<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>rwv-article-meta</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>router-link</span> <span class="token attr-name">:to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{name: <span class="token punctuation">'</span>article<span class="token punctuation">'</span>, params:{<span class="token punctuation">'</span>slug<span class="token punctuation">'</span>: article.slug}}<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>preview-link<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>h1</span><span class="token punctuation">></span></span>{{article.title}}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</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 punctuation">></span></span>{{article.description}}<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>span</span><span class="token punctuation">></span></span>Read more...<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</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 attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-list<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>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-default tag-pill tag-outline<span class="token punctuation">"</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>(tag, index) of article.tagList<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>tag + index<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> {{ tag }} <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> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>router-link</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">import</span> RwvArticleMeta <span class="token keyword">from</span> <span class="token string">"@/components/AricleMeta"</span><span class="token punctuation">;</span> <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">"RwvArticlePreview"</span><span class="token punctuation">,</span> props<span class="token punctuation">:</span> <span class="token punctuation">{</span> article<span class="token punctuation">:</span> <span class="token punctuation">{</span> type<span class="token punctuation">:</span> Object<span class="token punctuation">,</span> required<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> components<span class="token punctuation">:</span> <span class="token punctuation">{</span> RwvArticleMeta <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> |
Components này có nhiệm vụ render ra một list các bài báo dưới dạng preview để người dùng click vào đọc, rất đơn giản vậy thôi. Nhìn vào có thể thấy components này còn khá là rối rắm, đấy là nó còn đơn giản, chứ phải mấy components mà có thêm form với cả các tác vụ xử lý nữa lên tầm 300 dòng code thì các bạn nghĩ xem sẽ thối đến mức nào
Bây giờ chúng ta sẽ đi refactor lại nó, có thể cách làm của mình không phải tốt nhất nên mình mong sẽ nhận được các ý kiến đóng góp trong phần comment (bow)
1. Sử dụng Import Components hiệu quả
Ở ngay dòng Import đầu tiên các bạn có thể thấy mình đang dùng alias của webpack để thực hiện import component RwvArticleMeta, ký tự @
ở đây thay thế cho đường dẫn root của project đến component mà mình cần. Rất ngắn gọn nhưng chưa thật sự hiệu quả, vì khi bạn cần chuyển từ webpack sang một module bundler khác thì có thể, module mới không hỗ trợ đường dẫn này.
Thực tế mình đã gặp trường hợp này khi thực hiện một project Vue nhỏ, ban đầu mình sử dụng Nuxt.js để code, mọi chuyện ok, nhưng đến khi nộp cho leader, anh leader lại muốn chuyển hết nó sang Vue template đơn giản vì project không cần SSR. Mình đem nó về và cắt hết các components sang chỗ mới, nhưng khi render thì lỗi tè le vì Vue template mới không sử dụng webpack nên không hỗ trợ express path @
.
Và thế là mình đã phải đổi hết sang như này:
1 2 3 4 5 6 | <span class="token comment">// từ</span> <span class="token keyword">import</span> RwvArticleMeta <span class="token keyword">from</span> <span class="token string">"@/components/ArticleMeta"</span><span class="token punctuation">;</span> <span class="token comment">//thành</span> <span class="token keyword">import</span> RwvArticleMeta <span class="token keyword">from</span> <span class="token string">"../../components/ArticleMeta"</span><span class="token punctuation">;</span> |
2. Sắp xếp các thuộc tính của Components
Cái này rất nhỏ thôi, đó là theo như document của Vue thì ta sẽ sắp xếp khai báo các props
sau components
, nhưng theo mình thì nên đặt props
ở sau, vì thường chúng ta sẽ sử dụng các props
trong methods, watch hoặc computed
nên đặt vậy cho dễ xem, đỡ phải kéo lên nhiều thôi chứ cũng không có gì :v
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 | <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> name<span class="token punctuation">:</span> <span class="token string">"RwvArticlePreview"</span><span class="token punctuation">,</span> props<span class="token punctuation">:</span> <span class="token punctuation">{</span> article<span class="token punctuation">:</span> <span class="token punctuation">{</span> type<span class="token punctuation">:</span> Object<span class="token punctuation">,</span> required<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> components<span class="token punctuation">:</span> <span class="token punctuation">{</span> RwvArticleMeta <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> <span class="token comment">// nên là</span> <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> name<span class="token punctuation">:</span> <span class="token string">"RwvArticlePreview"</span><span class="token punctuation">,</span> components<span class="token punctuation">:</span> <span class="token punctuation">{</span> RwvArticleMeta <span class="token punctuation">}</span><span class="token punctuation">,</span> props<span class="token punctuation">:</span> <span class="token punctuation">{</span> article<span class="token punctuation">:</span> <span class="token punctuation">{</span> type<span class="token punctuation">:</span> Object<span class="token punctuation">,</span> required<span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</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 punctuation">}</span><span class="token punctuation">,</span> watch<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 punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> |
3. PascalCase Components
Lại thêm một điều nhỏ nhặt đơn giản nữa mà mình đã làm rất nhiều đó là thay vì viết component dưới dạng HTML thì chuyển qua PascalCased, điều nhỏ nhặt này có thể tạo ra khác biệt lớn, giảm thời gian đọc code của các dev xuống.
Khi nhìn vào một component với rất nhiều các component được import, các dev sẽ có thể lướt qua ngay lập tức component nào được sử dụng ở đâu khi sử dụng cú pháp PascalCase, nhất là khi phải đọc code của một bạn khác. Mình dám cá là nó sướng mắt hơn nhiều so với custom HTML tag truyền thống
1 2 3 4 5 6 7 8 9 10 11 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rwv-article-meta</span> <span class="token attr-name">:article</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>article<span class="token punctuation">"</span></span> <span class="token attr-name">:isPreview</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<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>rwv-article-meta</span><span class="token punctuation">></span></span> // hãy làm thế này <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>RwvArticleMeta</span> <span class="token attr-name">:article</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>article<span class="token punctuation">"</span></span> <span class="token attr-name">:isPreview</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<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>RwvArticleMeta</span><span class="token punctuation">></span></span> |
4. Self-close elements
Lại một điều nhỏ nhặt nữa có thể giúp code của bạn bớt dài dòng đi rất nhiều. Hãy tích cực sử dụng chúng trừ khi bạn thật sự cần đặt một dòng plain text ở trong element đó
1 2 3 4 5 6 7 8 9 10 11 | <span class="token operator"><</span>RwvArticleMeta <span class="token punctuation">:</span>article<span class="token operator">=</span><span class="token string">"article"</span> <span class="token punctuation">:</span>isPreview<span class="token operator">=</span><span class="token string">"true"</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>RwvArticleMeta<span class="token operator">></span> <span class="token comment">// nên là</span> <span class="token operator"><</span>RwvArticleMeta <span class="token punctuation">:</span>article<span class="token operator">=</span><span class="token string">"article"</span> <span class="token punctuation">:</span>isPreview<span class="token operator">=</span><span class="token string">"true"</span> <span class="token operator">/</span><span class="token operator">></span> |
5. Rút gọn các Props
Đôi khi chúng ta cần truyền các props là các giá trị Boolean, những lúc như thế không cần truyền cho chúng giá trị true hay false, chỉ cần đặt nó vào trong component là được rồi, nếu chúng được đặt ở đó, Vue sẽ mặc định ghi nhận giá trị true, ngược lại là false
1 2 3 4 5 6 7 8 9 10 11 | <span class="token operator"><</span>RwvArticleMeta <span class="token punctuation">:</span>article<span class="token operator">=</span><span class="token string">"article"</span> <span class="token punctuation">:</span>isPreview<span class="token operator">=</span><span class="token string">"true"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token comment">// nên là</span> <span class="token operator"><</span>RwvArticleMeta <span class="token punctuation">:</span>article<span class="token operator">=</span><span class="token string">"article"</span> <span class="token punctuation">:</span>isPreview <span class="token operator">/</span><span class="token operator">></span> |
6. Truyền tham số ngắn gọn
Đôi khi bạn sẽ muốn truyền sang phía component con một vài tham số là kiểu Object, hoặc kiểu mảng và dĩ nhiên là chúng khá là dài, lúc này đừng quên bạn có một công cụ tuyệt vời: Computed.
Ở ví dụ dưới đây bạn có thể thấy, component router-link
được truyền vào một tham số to
, hiện nó đang là một object khá dài, chúng ta sẽ đưa toàn bộ phần giá trị này vào một hàm Computed
là articleLink()
. Lúc này trên template của bạn, articleLink
sẽ được coi như một value để sử dụng.
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 | <span class="token operator"><</span>router<span class="token operator">-</span>link <span class="token punctuation">:</span>to<span class="token operator">=</span><span class="token string">"{name: 'article', params:{'slug': article.slug}}"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"preview-link"</span><span class="token operator">></span> <span class="token comment">//...</span> <span class="token operator"><</span><span class="token operator">/</span>router<span class="token operator">-</span>link<span class="token operator">></span> <span class="token comment">// nên là</span> <span class="token operator"><</span>router<span class="token operator">-</span>link <span class="token punctuation">:</span>to<span class="token operator">=</span><span class="token string">"articleLink"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"preview-link"</span><span class="token operator">></span> <span class="token comment">//...</span> <span class="token operator"><</span><span class="token operator">/</span>router<span class="token operator">-</span>link<span class="token operator">></span> <span class="token operator"><</span>script<span class="token operator">></span> <span class="token keyword">import</span> RwvArticleMeta <span class="token keyword">from</span> <span class="token string">"@/components/AricleMeta"</span><span class="token punctuation">;</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> article<span class="token punctuation">:</span> <span class="token punctuation">{</span> type<span class="token punctuation">:</span> Object<span class="token punctuation">,</span> required<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> computed<span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token function">articleLink</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> name<span class="token punctuation">:</span> <span class="token string">'article'</span><span class="token punctuation">,</span> params<span class="token punctuation">:</span> <span class="token punctuation">{</span> slug<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>slug <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> |
7. Đưa tất cả element vào trong HTML tag
Trong đa số các trường hợp, bạn nên đặt tất cả các element của mình vào trong một tag HTML, kể cả nó là plain text. Có thể là một thẻ span hoặc div nào đó cũng được, điều này để phục vụ cho công việc sau này, biết đâu trong tương lai bạn sẽ cần sử dụng if else trên element đó, hoặc đơn giản là bạn cần css cho dòng plain text đó.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-default tag-pill tag-outline<span class="token punctuation">"</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>(tag, index) of article.tagList<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>tag + index<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> {{ tag }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span> // nên là <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-default tag-pill tag-outline<span class="token punctuation">"</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>(tag, index) of article.tagList<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>tag + index<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>span</span><span class="token punctuation">></span></span>{{ tag }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</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 punctuation">></span></span> |
8. Dùng v-text thay cho cú pháp mustache
Nếu bạn đọc trong document của Vue bạn sẽ không thấy các refactor này đâu vì nó là một trick đơn giản giúp bạn tránh được một số lỗi không đáng có.
Cụ thể là khi bạn gửi một HTTP request để lấy data và đổ vào template như ví dụ 7, nếu dữ liệu trả về không có giá trị tag
thì rất có thể component sẽ báo lỗi undefined và lỗi gì đó trông kỳ cục, ảnh hưởng xấu đến trải nghiệm của người dùng.
Để xử lý vấn đề này, thay vì trực tiếp đổ dữ liệu như ở trên, hãy đưa nó vào directive v-text
, vấn đề này có thể được giải quyết. Hơn thế nữa, với trick này, bạn sẽ có thể sử dụng kèm thêm trick số 4, self-close luôn cả HTML tag này vào, code trông sẽ gọn đi khá là nhiều.
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>router-link</span> <span class="token attr-name">:to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>articleLink<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>preview-link<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>h1</span><span class="token punctuation">></span></span>{{article.title}}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</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 punctuation">></span></span>{{article.description}}<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>span</span><span class="token punctuation">></span></span>Read more...<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</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 attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-list<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>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-default tag-pill tag-outline<span class="token punctuation">"</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>(tag, index) of article.tagList<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>tag + index<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> {{ tag }} <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> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>router-link</span><span class="token punctuation">></span></span> //nên là <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>router-link</span> <span class="token attr-name">:to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>articleLink<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>preview-link<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>h1</span> <span class="token attr-name">v-text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>article.title<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-text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>article.description<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>span</span><span class="token punctuation">></span></span>Read more...<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</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 attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-list<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>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-default tag-pill tag-outline<span class="token punctuation">"</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>(tag, index) of article.tagList<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>tag + index<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>span</span> <span class="token attr-name">v-text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag<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>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> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>router-link</span><span class="token punctuation">></span></span> |
9. Extract Components
Khi thấy có một số thành phần trong component lặp đi lặp lại, bạn nên nghĩ ngay đến việc tách chúng sang làm một component con để tái sử dụng, tránh việc lặp lại code không cần thiết và nếu có thay đổi gì sẽ chỉ cần thay đổi ở một chỗ.
Chính ở phần giới thiệu đầu tiên mình đã mắc phải lỗi này, do quá tham code mà đã quên mất việc tách component ra, khiến cho code bị đội vốn lên đến 300 dòng và rất nhiều phần bị lặp lại, bây giờ để bảo trì lại thật sự là mất quá nhiều thời gian, thà đập quách đi xây lại cho nhanh.
Ở ví dụ trên, chúng ta có thể thấy mình có một tag li được cho vào vòng lặp, vậy nên không có lý do gì mà không tách nó làm một component riêng, được tái sử dụng nhiều lần, đừng vì lười tạo ra một file mới mà cứ để nguyên vậy như mình, sau này mới thấy rắc rối mà không sửa được
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>router-link</span> <span class="token attr-name">:to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>articleLink<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>preview-link<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>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-list<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>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-default tag-pill tag-outline<span class="token punctuation">"</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>(tag, index) of article.tagList<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>tag + index<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>span</span> <span class="token attr-name">v-text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag<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>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> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>router-link</span><span class="token punctuation">></span></span> // nên là <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>router-link</span> <span class="token attr-name">:to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>articleLink<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>preview-link<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>TagList</span> <span class="token attr-name">:tags</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>article.tagList<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>router-link</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">import</span> TagList <span class="token keyword">from</span> <span class="token string">'./TagList.vue'</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> components<span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token comment">//...,</span> TagList <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> |
TagList.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <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>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-list<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>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag-default tag-pill tag-outline<span class="token punctuation">"</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>(tag, index) of tags<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> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">v-text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tag<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>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> <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">"TagList"</span><span class="token punctuation">,</span> props<span class="token punctuation">:</span> <span class="token punctuation">{</span> tags<span class="token punctuation">:</span> Array <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> |
Lời kết
Đó là một số cách cơ bản để có thể thực hiện refactoring code mà mình biết trong quá trình làm việc với Vue.
Tất nhiên là còn nhiều thủ thuật nữa từ cơ bản đến nâng cao, qua quá trình làm việc dần dà bạn sẽ tự học được cho mình thêm các cách để code clean hơn, tăng hiệu quả công việc.
Với một số cách refactor code nâng cao hơn, bạn có thể sẽ muốn đọc lại bài viết này của mình: Xây dựng Vue Components một cách xịn xò hơn
Cám ơn đã theo dõi bài viết!