Giới thiệu
Chào các bạn, hiện tại VueJS đã là một trong những javascript framework lớn nhất hiện nay với hơn 155K trên Github. Hiện tại gần tết rồi, chắc mọi người sẽ mong ngóng tết đến và đếm lùi ngày đến tết =))
Trong bài viết này mình sẽ giới thiệu về Vue-CLI và tạo một landing page đếm lùi ngày đến tết các bạn nhé
Vue-CLI
Vue-CLI là một CLI (CLI – Command Line Interface) giúp xây dựng một Vue template project nhanh chóng thông qua các command line.
Cài đặt
Chúng ta có thể cài đặt Vue-CLI thông qua NPM hoặc Yarn, tất nhiên là máy đã cài node các bạn nhé
Cài đặt thông qua command:
1 2 | <span class="token function">npm</span> <span class="token function">install</span> <a href="/cdn-cgi/l/email-protection" class="__cf_email__">[email protected]</a> -g |
Tương tự với Yarn
1 2 | yarn add -global vue-cli |
Init project
Để tạo project mới qua Vue-CLI chúng sử dụng command:
1 2 | vue init webpack project-name |
Sau khi chạy bạn sẽ được hỏi về một số option như: Tên project, mô tả, sử dụng bộ complie nào, có sử dụng ESlint hay không, có unit test hay không,…?
Sau khi tạo xong project:
Code flow, Project structure
Một số command được setting sẵn, các bạn có thể tìm thấy ở file README.md
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token comment"># install dependencies</span> <span class="token function">npm</span> <span class="token function">install</span> <span class="token comment"># serve with hot reload at localhost:8080</span> <span class="token function">npm</span> run dev <span class="token comment"># build for production with minification</span> <span class="token function">npm</span> run build <span class="token comment"># build for production and view the bundle analyzer report</span> <span class="token function">npm</span> run build --report |
Project structure:
build: Build project thông qua webpack.
config: Chứa config về webserver, env.
node_modules: Chứa các modules được kéo về qua NPM/Yarn.
src: Chúng ta sẽ code Vue tại đây.
static: Chứa các static resources.
Code flow
Sau chạy command npm run dev
, lúc này một server ảo sẽ chạy tại cổng 8080
, có tác dụng serve file index.html
.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token doctype"><!DOCTYPE html></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>utf-8<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>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>width=device-width,initial-scale=1.0<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>title</span><span class="token punctuation">></span></span>count-down<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</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>div</span><span class="token punctuation">></span></span> <span class="token comment"><!-- built files will be auto injected --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>html</span><span class="token punctuation">></span></span> |
Trong thư mục src, file main.js
sẽ được chạy đầu tiên, Vue app sẽ được tạo tại đây
1 2 3 4 5 6 7 8 9 10 11 12 13 | <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> App <span class="token keyword">from</span> <span class="token string">'./App'</span> <span class="token keyword">import</span> router <span class="token keyword">from</span> <span class="token string">'./router'</span> Vue<span class="token punctuation">.</span>config<span class="token punctuation">.</span>productionTip <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token keyword">new</span> <span class="token class-name">Vue</span><span class="token punctuation">(</span><span class="token punctuation">{</span> el<span class="token punctuation">:</span> <span class="token string">'#app'</span><span class="token punctuation">,</span> router<span class="token punctuation">,</span> components<span class="token punctuation">:</span> <span class="token punctuation">{</span> App <span class="token punctuation">}</span><span class="token punctuation">,</span> template<span class="token punctuation">:</span> <span class="token string">'<App/>'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> |
Vue app khởi tạo đồng thời sẽ render một component có tên là App, chính là file App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token operator"><</span>template<span class="token operator">></span> <span class="token operator"><</span>div id<span class="token operator">=</span><span class="token string">"app"</span><span class="token operator">></span> <span class="token operator"><</span>img src<span class="token operator">=</span><span class="token string">"./assets/logo.png"</span><span class="token operator">></span> <span class="token operator"><</span>router<span class="token operator">-</span>view<span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>template<span class="token operator">></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">'App'</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 operator"><</span>style<span class="token operator">></span> #app <span class="token punctuation">{</span> font<span class="token operator">-</span>family<span class="token punctuation">:</span> <span class="token string">'Avenir'</span><span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans<span class="token operator">-</span>serif<span class="token punctuation">;</span> <span class="token operator">-</span>webkit<span class="token operator">-</span>font<span class="token operator">-</span>smoothing<span class="token punctuation">:</span> antialiased<span class="token punctuation">;</span> <span class="token operator">-</span>moz<span class="token operator">-</span>osx<span class="token operator">-</span>font<span class="token operator">-</span>smoothing<span class="token punctuation">:</span> grayscale<span class="token punctuation">;</span> text<span class="token operator">-</span>align<span class="token punctuation">:</span> center<span class="token punctuation">;</span> color<span class="token punctuation">:</span> #<span class="token number">2</span>c3e50<span class="token punctuation">;</span> margin<span class="token operator">-</span>top<span class="token punctuation">:</span> <span class="token number">60</span>px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>style<span class="token operator">></span> |
Trong App component, có một component là <router-view/>
, component này có tác dụng inject các component con dựa vào router
.
Router của Vue app lúc này sẽ là file src/router/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <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> HelloWorld <span class="token keyword">from</span> <span class="token string">'@/components/HelloWorld'</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 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> routes<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">'/'</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'HelloWorld'</span><span class="token punctuation">,</span> component<span class="token punctuation">:</span> HelloWorld <span class="token punctuation">}</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> |
Vậy khi bạn truy cập vào http://localhost:8080/
component HelloWorld
sẽ được inject vào bên trong component App
Xây dựng landing page đếm ngược
Sau khi hiểu về luồng và cấu trúc thư mục, chúng sẽ bắt đầu xây dựng một component mới các bạn nhé
Chỉnh sửa lại sample code
Mình vẫn sẽ giữ nguyên luồng chạy của Vue app, tại file /src/App.vue
mình sẽ bỏ bớt code mẫu đi, chỉ giữ lại:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token operator"><</span>template<span class="token operator">></span> <span class="token operator"><</span>div id<span class="token operator">=</span><span class="token string">"app"</span><span class="token operator">></span> <span class="token operator"><</span>router<span class="token operator">-</span>view<span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>template<span class="token operator">></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">'App'</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 operator"><</span>style<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>style<span class="token operator">></span> |
Tại /src/components
chúng ta sẽ tạo component mới tên là CountDown.vue
, đồng thời sẽ sửa lại router một chút, khi truy cập /
sẽ render component CountDown
thay cho HelloWorld
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <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> CountDown <span class="token keyword">from</span> <span class="token string">'../components/CountDown'</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 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> 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">'count-down'</span><span class="token punctuation">,</span> component<span class="token punctuation">:</span> CountDown<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> |
Mình sẽ template trước khi xử lý logic:
Lưu ý: Những file ảnh chúng ta sẽ đặt tại thư mục /src/assets
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | <span class="token operator"><</span>template<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"main"</span><span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"countdown"</span><span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> day <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Ngày<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> hour <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Giờ<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> minute <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Phút<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> second <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Giây<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>template<span class="token operator">></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">'CountDown'</span><span class="token punctuation">,</span> data<span class="token punctuation">:</span> <span class="token keyword">function</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> day<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> hour<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> minute<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> second<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 operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> <span class="token operator"><</span>style scoped<span class="token operator">></span> @<span class="token keyword">import</span> <span class="token function">url</span><span class="token punctuation">(</span>https<span class="token punctuation">:</span><span class="token operator">/</span><span class="token operator">/</span>fonts<span class="token punctuation">.</span>googleapis<span class="token punctuation">.</span>com<span class="token operator">/</span>css<span class="token operator">?</span>family<span class="token operator">=</span>Roboto<span class="token operator">+</span>Condensed<span class="token punctuation">:</span><span class="token number">400</span><span class="token operator">|</span>Roboto<span class="token punctuation">:</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">.</span>main <span class="token punctuation">{</span> align<span class="token operator">-</span>items<span class="token punctuation">:</span> center<span class="token punctuation">;</span> bottom<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> width<span class="token punctuation">:</span> <span class="token number">100</span><span class="token operator">%</span><span class="token punctuation">;</span> background<span class="token operator">-</span>image<span class="token punctuation">:</span> <span class="token function">url</span><span class="token punctuation">(</span><span class="token string">"<a href="/cdn-cgi/l/email-protection" class="__cf_email__">[email protected]</a>/assets/bg.jpg"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> display<span class="token punctuation">:</span> flex<span class="token punctuation">;</span> justify<span class="token operator">-</span>content<span class="token punctuation">:</span> center<span class="token punctuation">;</span> left<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> position<span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> right<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> top<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> background<span class="token operator">-</span>position<span class="token punctuation">:</span> center<span class="token punctuation">;</span> background<span class="token operator">-</span>repeat<span class="token punctuation">:</span> no<span class="token operator">-</span>repeat<span class="token punctuation">;</span> background<span class="token operator">-</span>size<span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span>countdown <span class="token punctuation">{</span> display<span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span>block <span class="token punctuation">{</span> display<span class="token punctuation">:</span> flex<span class="token punctuation">;</span> flex<span class="token operator">-</span>direction<span class="token punctuation">:</span> column<span class="token punctuation">;</span> margin<span class="token punctuation">:</span> <span class="token number">20</span>px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span>text <span class="token punctuation">{</span> color<span class="token punctuation">:</span> #ffffff<span class="token punctuation">;</span> font<span class="token operator">-</span>size<span class="token punctuation">:</span> <span class="token number">25</span>px<span class="token punctuation">;</span> font<span class="token operator">-</span>family<span class="token punctuation">:</span> <span class="token string">'Roboto Condensed'</span><span class="token punctuation">,</span> serif<span class="token punctuation">;</span> font<span class="token operator">-</span>weight<span class="token punctuation">:</span> <span class="token number">40</span><span class="token punctuation">;</span> margin<span class="token operator">-</span>top<span class="token punctuation">:</span> <span class="token number">10</span>px<span class="token punctuation">;</span> margin<span class="token operator">-</span>bottom<span class="token punctuation">:</span> <span class="token number">10</span>px<span class="token punctuation">;</span> text<span class="token operator">-</span>align<span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span>digit <span class="token punctuation">{</span> color<span class="token punctuation">:</span> #ecf0f1<span class="token punctuation">;</span> font<span class="token operator">-</span>size<span class="token punctuation">:</span> <span class="token number">130</span>px<span class="token punctuation">;</span> font<span class="token operator">-</span>weight<span class="token punctuation">:</span> <span class="token number">100</span><span class="token punctuation">;</span> font<span class="token operator">-</span>family<span class="token punctuation">:</span> <span class="token string">'Roboto'</span><span class="token punctuation">,</span> serif<span class="token punctuation">;</span> margin<span class="token punctuation">:</span> <span class="token number">10</span>px<span class="token punctuation">;</span> text<span class="token operator">-</span>align<span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>style<span class="token operator">></span> |
Sau khi xong template, lúc này bắt đầu xử lý logic các bạn nhé
Đếm ngược
Trong một Vue component sẽ có các method đại diện cho từng giai đoạn của Lifecycle Hooks.
Tại method created
:
1 2 3 4 5 6 7 | <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setInterval</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> currentDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</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">calculateETA</span><span class="token punctuation">(</span>currentDate<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> |
Khi component được tạo chúng sẽ sử dụng method setInterval
với step là 1s với mục đích là 1s sẽ lấy lại thời gian hiện tại 1 lần, sau đó xử lý tính toán tại method calculateETA
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token function">calculateETA</span> <span class="token punctuation">(</span>currentDate<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> destinationDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">'2020-01-25'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setHours</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">let</span> diff <span class="token operator">=</span> destinationDate <span class="token operator">-</span> currentDate <span class="token keyword">let</span> milliseconds <span class="token operator">=</span> diff <span class="token operator">%</span> <span class="token number">1000</span> diff <span class="token operator">=</span> <span class="token punctuation">(</span>diff <span class="token operator">-</span> <span class="token punctuation">(</span>milliseconds<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">1000</span> <span class="token keyword">this</span><span class="token punctuation">.</span>second <span class="token operator">=</span> diff <span class="token operator">%</span> <span class="token number">60</span> diff <span class="token operator">=</span> <span class="token punctuation">(</span>diff <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>second<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">60</span> <span class="token keyword">this</span><span class="token punctuation">.</span>minute <span class="token operator">=</span> diff <span class="token operator">%</span> <span class="token number">60</span> diff <span class="token operator">=</span> <span class="token punctuation">(</span>diff <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>minute<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">60</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hour <span class="token operator">=</span> diff <span class="token operator">%</span> <span class="token number">24</span> <span class="token keyword">this</span><span class="token punctuation">.</span>day <span class="token operator">=</span> <span class="token punctuation">(</span>diff <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>hour<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">24</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> |
const destinationDate = new Date('2020-01-25').setHours(0, 0, 0, 0)
chính là mùng 1 Tết, vì Việt Nam ở múi giờ +7, nếu new Date('2020-01-25')
sẽ trả về kết quả là 7h sáng ngày 25/01/2020, vậy nên cần set thêm setHours(0, 0, 0, 0)
để thời gian chính là giao thừa các bạn nhé
Như vậy xem như đã hoàn thành rồi, nhưng chúng ta sẽ chỉnh lại một chút để cho đồng bộ số degit, vì ngày hiện tại có 2 chữ số, mà giờ, phút, giây nếu <10 chỉ có một, trông không đẹp cho lắm nhỉ =))
Thêm một số computed:
1 2 3 4 5 6 7 8 9 10 11 12 | computed<span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token function">hourETA</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 keyword">this</span><span class="token punctuation">.</span>hour <span class="token operator">>=</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hour <span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`0</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>hour<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">minuteETA</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 keyword">this</span><span class="token punctuation">.</span>minute <span class="token operator">>=</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token keyword">this</span><span class="token punctuation">.</span>minute <span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`0</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>minute<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">secondETA</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 keyword">this</span><span class="token punctuation">.</span>second <span class="token operator">>=</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token keyword">this</span><span class="token punctuation">.</span>second <span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`0</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>second<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> |
Đổi lại template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token operator"><</span>template<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"main"</span><span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"countdown"</span><span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> day <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Ngày<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> hourETA <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Giờ<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> minuteETA <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Phút<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"block"</span><span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"digit"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> secondETA <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"text"</span><span class="token operator">></span>Giây<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>template<span class="token operator">></span> |
Okay, vậy là đã hoàn thành rồi…
Truy cập vào http://localhost:8080/
để xem thành quả nào
Tại thời điểm mình viết bài hơn 2 tuần nữa mới tết cơ =))
Sau khi hoàn thành, nếu muốn deploy các bạn có thể sử dụng npm run build
, webpack sẽ build project ra các file tại /dist
.
Lưu ý file index.html
cần chạy qua webserver mới có thể hiển thị được các bạn nhé.
Code demo: https://github.com/hoangtm1601/bao-gio-den-tet
Xem luôn bao giờ đến tết: https://hoangtm1601.github.io/