Mở đầu
Xin chào các bạn tiếp tục với series về vuejs hôm nay mình ĩn giới thiệu với các bạn về Vue router.
Hiện nay ứng dụng một trang SPA (Single Page Application) ngày đang một phổ biến. Là một trang web chỉ trên một trang, tức là thay vì load cả trang web để lấy tất cả những nội dung đã load trước đó rồi thì SPA sẽ làm nhiệm vụ chỉ load những phần cần thay đổi, những phần nào không thay đổi sẽ không cần load để giảm tải cho server và làm cho trang web của chúng ta nhanh hơn, chuyên nghiệp hơn. Đặc biệt làm cho trải nghiệm của người dùng được tốt hơn.
Vue Router là gì?
Vue Router là bộ định tuyến chính thức cho Vue.js. Nó tích hợp sâu với lõi Vue.js để làm cho việc xây dựng các Single Page Applications với Vue.js trở nên dễ dàng.
Hướng dẫn sử dụng
Ở bài này mình xin demo luôn với laravel 5.8 nhé.
Đầu tiên các bạn cần install laravel :
1 2 | composer create<span class="token operator">-</span>project <span class="token operator">--</span>prefer<span class="token operator">-</span>dist laravel<span class="token operator">/</span>laravel vue_router <span class="token number">5.8</span><span class="token punctuation">.</span><span class="token operator">*</span> |
tiếp đó mình install vue router nhé
1 2 | npm install <span class="token operator">--</span>save vue vue<span class="token operator">-</span>router |
Vì laravel đã tích hợp sẵn vuejs vào project rồi nên chúng ta cũng không cần làm gì nhiều cả. Chỉ cần nhúng file script chúng ta build vào là được.
Chúng ta sẽ điều hướng cho laravel mặc định vào 1 file view duy nhất như sau:
1 2 3 | Route<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">view</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'/{any}'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'home'</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'any'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'.*'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Ở đây tại file web.php
mình để router của laravel điều hướng vào 1 file view duy nhất. Trong file view này sẽ nhúng file js chúng ta đã build và từ đó file js này sẽ điều hướng đến các view cần thiết.
tại file view home.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token operator"><</span><span class="token operator">!</span><span class="token constant">DOCTYPE</span> <span class="token constant">HTML</span> <span class="token keyword">PUBLIC</span> <span class="token double-quoted-string string">"-//W3C//DTD HTML 4.01//EN"</span> <span class="token double-quoted-string string">"http://www.w3.org/TR/html4/strict.dtd"</span><span class="token operator">></span> <span class="token operator"><</span>html lang<span class="token operator">=</span><span class="token double-quoted-string string">"en"</span><span class="token operator">></span> <span class="token operator"><</span>head<span class="token operator">></span> <span class="token operator"><</span>meta http<span class="token operator">-</span>equiv<span class="token operator">=</span><span class="token double-quoted-string string">"Content-Type"</span> content<span class="token operator">=</span><span class="token double-quoted-string string">"text/html;charset=UTF-8"</span><span class="token operator">></span> <span class="token operator"><</span>title<span class="token operator">></span>Home<span class="token operator"><</span><span class="token operator">/</span>title<span class="token operator">></span> <span class="token operator"><</span>link rel<span class="token operator">=</span><span class="token double-quoted-string string">"stylesheet"</span> href<span class="token operator">=</span><span class="token double-quoted-string string">"/css/style.css"</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>head<span class="token operator">></span> <span class="token operator"><</span>body<span class="token operator">></span> <span class="token operator"><</span>div id<span class="token operator">=</span><span class="token double-quoted-string string">"app"</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>script src<span class="token operator">=</span><span class="token double-quoted-string string">"/js/app.js"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>body<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>html<span class="token operator">></span> |
Như các bạn thấy thì mình chỉ nhúng file app.js đc build từ các component vuejs và các file js cần thiết khác.
Laravel cấu hình để build các file này tại file webpack.mix.js bằng Laravel mix. Các bạn có thể xem thêm về Laravel mix tại bài viết này của mình.
Và sau khi build xong ta có đc file tại public/app.js
và từ đó ta chỉ cần import vào file view home của chúng ta.
Để build các bạn thực hiện lệnh
1 2 3 4 | npm run dev hoặc npm run watch <span class="token comment">// lệnh này sẽ theo dõi luôn khi nào có file thay đổi sẽ build lại cho chúng ta luôn.</span> |
Tiếp theo mình sẽ tạo 3 component như sau:
mình sẽ tạo 3 component tại thư mục resource/js/components
1 2 3 4 | App - component chính Home - component cho trang home User - component cho trang user |
Nội dung của 3 file này sẽ như sau:
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 | <span class="token comment">//App.vue</span> <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">"container"</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">"header"</span><span class="token operator">></span> <span class="token operator"><</span>ul <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav justify-content-center"</span><span class="token operator">></span> <span class="token operator"><</span>li <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-item"</span><span class="token operator">></span> <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">""</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-link"</span><span class="token operator">></span> Home <span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>li<span class="token operator">></span> <span class="token operator"><</span>li <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-item"</span><span class="token operator">></span> <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">""</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-link"</span><span class="token operator">></span> User <span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>li<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>ul<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">"main mt-4"</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">"row"</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">"col-md-8 offset-2 text-center"</span><span class="token operator">></span> <span class="token operator"><</span>p<span class="token operator">></span>This is App component<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>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 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 punctuation">.</span>container <span class="token punctuation">{</span> border<span class="token punctuation">:</span> <span class="token number">1</span>px solid #eee<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span>active <span class="token punctuation">{</span> color<span class="token punctuation">:</span> red <span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>style<span class="token operator">></span> |
Tại file User như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token comment">// User.vue</span> <span class="token operator"><</span>template<span class="token operator">></span> <span class="token operator"><</span>div<span class="token operator">></span> <span class="token operator"><</span>h4<span class="token operator">></span>Hello<span class="token punctuation">,</span> This is user page<span class="token operator"><</span><span class="token operator">/</span>h4<span class="token operator">></span> <span class="token operator"><</span>p<span class="token operator">></span>We are Sun<span class="token operator">*</span><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>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">'User'</span> <span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> |
Tiếp theo ta tạo 1 file routes.js tại thư mục js/ với nội dung như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <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> User <span class="token keyword">from</span> <span class="token string">'./components/User'</span> <span class="token keyword">const</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> component<span class="token punctuation">:</span> Home<span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'index'</span><span class="token punctuation">,</span> <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">'/users'</span><span class="token punctuation">,</span> component<span class="token punctuation">:</span> User<span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'user'</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> routes<span class="token punctuation">;</span> |
Ở đây:
path
: là đường dẫn hiển thị trên thanh địa chỉ, component
: là component sẽ được render vào layoutname
: dùng để sử dụng để định danh route, giúp cho chúng ta có thể sử dụng một cách thuận tiện hơn.
Ngoài ra còn có rất nhiều thuộc tính khác, các bạn có thể tham khảo ở link tài liệu https://router.vuejs.org/guide/essentials/named-routes.html
Tiếp theo tại file js/app.js sẽ chỉnh sửa lại như sau để import vue-router và khai báo 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 | <span class="token comment">//app.js</span> <span class="token comment">// khai báo các component</span> Vue<span class="token punctuation">.</span><span class="token function">component</span><span class="token punctuation">(</span><span class="token string">'home'</span><span class="token punctuation">,</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./components/Home'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Vue<span class="token punctuation">.</span><span class="token function">component</span><span class="token punctuation">(</span><span class="token string">'user'</span><span class="token punctuation">,</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./components/User'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Vue<span class="token punctuation">.</span><span class="token function">component</span><span class="token punctuation">(</span><span class="token string">'app'</span><span class="token punctuation">,</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./components/App'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// import vue router, component và routes</span> <span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">'./components/App'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> VueRouter <span class="token keyword">from</span> <span class="token string">'vue-router'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> routes <span class="token keyword">from</span> <span class="token string">'./routes'</span><span class="token punctuation">;</span> <span class="token comment">// use router</span> Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>VueRouter<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// khai báo dùng router này</span> <span class="token keyword">const</span> router <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">VueRouter</span><span class="token punctuation">(</span><span class="token punctuation">{</span> routes<span class="token punctuation">,</span> mode<span class="token punctuation">:</span> <span class="token string">'history'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// và cuối cùng là tạo 1 instance Vue và render tại phần tử có id là app,</span> <span class="token comment">// render tại component App và dùng router đã khai báo ở trên</span> <span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vue</span><span class="token punctuation">(</span><span class="token punctuation">{</span> el<span class="token punctuation">:</span> <span class="token string">'#app'</span><span class="token punctuation">,</span> render<span class="token punctuation">:</span> h <span class="token operator">=></span> <span class="token function">h</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span><span class="token punctuation">,</span> router <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Ở trên có đoạn như sau:
1 2 3 4 5 | <span class="token keyword">const</span> router <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">VueRouter</span><span class="token punctuation">(</span><span class="token punctuation">{</span> routes<span class="token punctuation">,</span> mode<span class="token punctuation">:</span> <span class="token string">'history'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
ở đây có đoạn mode: ‘history’ có tác dụng như sau:
Khi ko có đoạn mode này mặc định khi vào các đường dẫn sẽ chúng ta sẽ có thêm dấu #
trên trình duyệt
Ví dụ: localhost/#/user
Ok, xem npm đã build xong chưa, rồi ra ngoài load trình duyệt xem đã vào đc view home và load đc nội dung trong component App.vue ra chưa:
Và bước cuối cùng tại file App.vue ta sửa lại như sau:
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 | <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">"container"</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">"header"</span><span class="token operator">></span> <span class="token operator"><</span>ul <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav justify-content-center"</span><span class="token operator">></span> <span class="token operator"><</span>li <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-item"</span><span class="token operator">></span> <span class="token operator"><</span>router<span class="token operator">-</span>link <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-link"</span> <span class="token punctuation">:</span><span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"[{active: $route.name === 'index'}]"</span> <span class="token punctuation">:</span>to<span class="token operator">=</span><span class="token string">"{name: 'index'}"</span> <span class="token operator">></span> Home <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><span class="token operator">/</span>li<span class="token operator">></span> <span class="token operator"><</span>li <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-item"</span><span class="token operator">></span> <span class="token operator"><</span>router<span class="token operator">-</span>link <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-link"</span> <span class="token punctuation">:</span><span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"[{active: $route.name === 'user'}]"</span> <span class="token punctuation">:</span>to<span class="token operator">=</span><span class="token string">"{name: 'user'}"</span> <span class="token operator">></span> User <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><span class="token operator">/</span>li<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>ul<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">"main mt-4"</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">"row"</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">"col-md-8 offset-2 text-center"</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>router<span class="token operator">-</span>view<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>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 punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> |
Chúng ta cần để ý 2 chỗ sau:
1 2 3 4 5 6 7 8 9 10 | <span class="token operator"><</span>router<span class="token operator">-</span>link <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"nav-link"</span> <span class="token punctuation">:</span><span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"[{active: $route.name === 'index'}]"</span> <span class="token punctuation">:</span>to<span class="token operator">=</span><span class="token string">"{name: 'index'}"</span> <span class="token operator">></span> Home <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">// Đây là 1 route điều hướng chúng ta đến route có name là index</span> <span class="token comment">// và sẽ thêm class là active nếu route name là index</span> |
Tiếp nữa là:
1 2 3 | <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>router<span class="token operator">-</span>view<span class="token operator">></span> <span class="token comment">// Chỗ này được hiểu là với mỗi route sẽ được load các component đã được khai báo trong file routes.js</span> |
Ra ngoài test lại:
Rất đơn giản phải không nào.