Đặt vấn đề
Cấu trúc một trang web thường được chia thành các phần như là Header, Content, Footer . Điều này đã được thực hiện theo cách truyền thống bằng cách sử dụng mô hình client/server
, trong đó mỗi trang phải được tải từ máy chủ với một URL khác nhau. Để điều hướng đến một trang mới, trình duyệt phải gửi yêu cầu tới URL của trang đó. Máy chủ sẽ gửi dữ liệu trở lại và trình duyệt có thể phải render một trang mới. Đối với kết nối internet trung bình, quá trình này có thể sẽ mất vài giây, trong thời gian đó, người dùng phải chờ trang mới tải. Tại sao chúng ta lại mất công ngồi đợi quá trình render một trang hoàn toàn mới với đủ thành phần trong khi cái mình cần thực sự chỉ là cái Content của nó ??
Khái Niệm SPA ra đời
Để giải quyết bài toán trên , có một kỹ thuật cũng khá là hay dùng đó là kỹ thuật SPA ( Single Page Application ) nôm là Ứng dụng trang đơn =)))))
Ưu điểm của SPA là nó có thể tạo ra trải nghiệm liền mạch hơn cho người dùng. Dữ liệu cho các trang mới vẫn phải được truy xuất và do đó sẽ tạo ra một số gián đoạn nhỏ đối với luồng của người dùng, nhưng sự gián đoạn này được giảm thiểu do việc truy xuất dữ liệu có thể được thực hiện không đồng bộ. Ngoài ra, vì các trang SPA thường yêu cầu ít dữ liệu hơn do sử dụng lại một số thành phần trang, tải trang nhanh hơn.
Hiểu một cách đơn giản, thì toàn bộ resource của web bao gồm các file CSS, Javascript, master layout hay cấu trúc web page sẽ được load lần đầu tiên khi chúng ta bắt đầu duyệt môt website A nào đó. Ở những lần sau, khi chuyển trang khác, client sẽ gửi những ajax request để get dữ liệu cần thiết( thường là phần nội dung). Khái niệm của SPA trên mạng rất là nhiều nên mình chỉ nói tới đây thôi . Mình cùng vào thực hành dựng SPA với Laravel và VueJS nhé
Cài đặt thư viện
Ở bài viết Laravel + Vue.js : Xử lý thông báo lỗi mình đã đề cập qua việc cài đặt cũng nhưng áp dụng VueJS vào Laravel rồi nên các bạn nào còn lan man phần này có thể xem qua nhé
Trong bài hướng dẫn này mình chỉ cần dùng thư viện duy nhất thôi đó là : Vue-Router , Các thư viện khác mình sẽ giới thiệu ở các phần sau
- Vue-router: giúp định tuyến trong ứng dụng (định nghĩa các route và mapping nó với các Vue component).
Các bạn chạy lệnh sau để tiến hành cài packge vue-router
1 2 | npm install vue-router |
Ok Xong nhé
Chỉnh sửa bố cục
Khi triển khai SPA giữa 2 thằng này thì các route mình sẽ dùng ở vue-router rồi nên chúng ta cần sửa lại 1 chút file routes/web.php của Laravel nhé
1 2 3 | <span class="token comment">// routes/web.php</span> Route<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">get</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">'<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e3b59686a08c8d97918c8f8f8691a38a8d87869b">[email protected]</a>'</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> |
Tạo một controller tên là VueController với nội dung
1 2 3 4 5 6 7 8 9 10 11 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation"></span>Http<span class="token punctuation"></span>Controllers</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation"></span>Http<span class="token punctuation"></span>Request</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">VueController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">index</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 function">view</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'app.index'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span> |
Lệnh trên khi có bất cứ request nào nó sẽ bay vào VueController function index để return về file index.blade.php
Tạo giúp mình file index.blade.php tại thư mục
resources/views/app/index.blade.php nhé
Nội dung của nó trông như thế này
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 | <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 attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{{ str_replace(<span class="token punctuation">'</span>_<span class="token punctuation">'</span>, <span class="token punctuation">'</span>-<span class="token punctuation">'</span>, app()->getLocale()) }}<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>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<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- CSRF Token --></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>csrf-token<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>{{ csrf_token() }}<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>{{ config('app.name', 'Laravel') }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token comment"><!-- Scripts --></span> <span class="token comment"><!-- Fonts --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>dns-prefetch<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>//fonts.gstatic.com<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>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>https://fonts.googleapis.com/css?family=Nunito<span class="token punctuation">"</span></span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- Styles --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{{ asset(<span class="token punctuation">'</span>css/app.css<span class="token punctuation">'</span>) }}<span class="token punctuation">"</span></span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>stylesheet<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>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 tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{{ mix(<span class="token punctuation">'</span>js/app.js<span class="token punctuation">'</span>) }}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script language-javascript"/><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>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> |
Quan trọng nhất là ở cái div app kia kìa , tại vì phần này mình sẽ chia bố cục Vue thành các Components và lát nữa đây ở file app.js mình sẽ render vào element #app
Trước hết các bạn xây dựng giúp mình bố cục components của Vue trông như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | -resources --js ---->components -------->content -------------->HelloWorld.vue // nội dung home -------------->ContentOne.vue // nội dung khi chuyển trang A -------------->ContentTwo.vue // Nội dung khi chuyển trang B -------->layouts // Chứa component chung của ứng dụng -------------->Header.vue -------->Index.vue // Component home định nghĩa bố cục của web sẽ nằm ở trong này ---->App.vue // File component tổng của ứng dụng từ đây nó sẽ link tới các content nằm trong components con qua router-view ---->app.js // Nơi khai báo thư viện và tạo instance Vue ---->routes.js // Định nghĩa các route |
Tiếp theo mình cần sửa lại một chút ở resources/js/app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./bootstrap'</span><span class="token punctuation">)</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> App <span class="token keyword">from</span> <span class="token string">'./App'</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> 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 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> 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><span class="token punctuation">;</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><span class="token punctuation">;</span> |
Nội dung file App.vue chỉ vỏn vẹn như này thôi
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>router-view</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>router-view</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span><span class="token punctuation">></span></span><span class="token script language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> name<span class="token punctuation">:</span> <span class="token string">'app'</span><span class="token punctuation">,</span> <span class="token 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> |
Viết 1 chút nội dung ở các file content nào tí nữa mình sẽ dùng vue-router kết nối chúng lại sau
HelloWorld.vue
1 2 3 4 5 6 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span>Hello World<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>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> |
ContentOne.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span>Content One<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> It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). <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>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> |
ContentTwo.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span>Content Two<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> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. <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>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> |
Giờ chúng ta sẽ tới phần định nghĩa các route tại routes.js
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 | <span class="token keyword">import</span> Index <span class="token keyword">from</span> <span class="token string">'./components/Index'</span> <span class="token keyword">import</span> HelloWorld <span class="token keyword">from</span> <span class="token string">'./components/content/HelloWorld'</span> <span class="token keyword">import</span> ContentOne <span class="token keyword">from</span> <span class="token string">'./components/content/ContentOne'</span> <span class="token keyword">import</span> ContentTwo <span class="token keyword">from</span> <span class="token string">'./components/content/ContentTwo'</span> <span class="token keyword">const</span> routes <span class="token operator">=</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">'/'</span><span class="token punctuation">,</span> component<span class="token punctuation">:</span> Index<span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'Index'</span><span class="token punctuation">,</span> redirect<span class="token punctuation">:</span> <span class="token string">'/home'</span><span class="token punctuation">,</span> children<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">'/home'</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> path<span class="token punctuation">:</span> <span class="token string">'ContentOne'</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'contentone'</span><span class="token punctuation">,</span> component<span class="token punctuation">:</span> ContentOne<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">'ContentTwo'</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'contentwo'</span><span class="token punctuation">,</span> component<span class="token punctuation">:</span> ContentTwo<span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> routes<span class="token punctuation">;</span> |
Ở trên các bạn có thể thấy khi người dùng truy cập path : “/” nó sẽ render ra component Index rồi nó thực hiện chuyển tới /home được định nghĩa phần children có component là HelloWorld. Tại sao nó lại nằm ở trong children nhỉ đơn giản thôi vì tí nữa file Index.vue mình sẽ chỉ định nghĩa bố cục trong đó có phần content là <router-view></router-view> Nó sẽ render ở trong cặp thẻ đó =))).
Nội dung Index.vue trông như này
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 tag"><span class="token tag"><span class="token punctuation"><</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>app-header</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>app-header</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>main</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>py-4<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>transition</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>slide-fade<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>router-view</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>router-view</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>transition</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>main</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> AppHeader <span class="token keyword">from</span> <span class="token string">'./layouts/Header'</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">'Index'</span><span class="token punctuation">,</span> components<span class="token punctuation">:</span> <span class="token punctuation">{</span> AppHeader<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>style</span> <span class="token attr-name">scoped</span><span class="token punctuation">></span></span><span class="token style language-css"> <span class="token selector">.slide-fade-enter-active</span> <span class="token punctuation">{</span> <span class="token property">transition</span><span class="token punctuation">:</span> all .3s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.slide-fade-leave-active</span> <span class="token punctuation">{</span> <span class="token property">transition</span><span class="token punctuation">:</span> all .8s <span class="token function">cubic-bezier</span><span class="token punctuation">(</span>1.0, 0.5, 0.8, 1.0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.slide-fade-enter, .slide-fade-leave-to</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span>10px<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>style</span><span class="token punctuation">></span></span> |
Ta thấy là phần đầu nó sẽ include vào component tên là AppHeader được định nghĩa ở Header.vue
và phần content sẽ nằm trong cặp thẻ <main></main>
Mình có thêm 1 cặp thẻ là <transition></transition> Để khi chuyển trang nó có tí mờ ảo ấy mà =))))
Về css hay transition các bạn có thể tham khảo trên link này nhé https://vuejs.org/v2/guide/transitions.html
Giờ là file Header.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 25 26 27 28 29 30 31 32 33 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>nav</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>navbar navbar-expand-md navbar-light bg-white shadow-sm<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>container<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 attr-name">to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/<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>navbar-brand<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Laravel<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>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>navbar-toggler<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>button<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">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>navbar-toggler-icon<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> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>collapse navbar-collapse<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>navbarSupportedContent<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- Left Side Of Navbar --></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>navbar-nav mr-auto<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 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>navbar-nav ml-auto<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>nav-item<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 attr-name">to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>contentone<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>nav-link<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Content One<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>li</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>nav-item<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 attr-name">to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>contenttwo<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>nav-link<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Content Two<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>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>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>nav</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>template</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span><span class="token punctuation">></span></span><span class="token script language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> name<span class="token punctuation">:</span> <span class="token string">'AppHeader'</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> |
Đó bạn thấy không , ở trên các đường dẫn chuyển trang mình không dùng thẻ a trong html, mà mình dùng router-link , có tham số to là path bạn muốn chuyển , về router-link nó còn nhiều tham số khác như là path hay name . Các bạn có thể tìm hiểu tại đây
https://router.vuejs.org/api/
Chạy và xem thành quả
Chạy ứng dụng với 2 lệnh sau
1 2 | php artisan serve && npm run dev |
Và truy cập http://localhost:8000 xem thành quả nhé đây là thành quả của mình
Các bạn cũng có thể tham khảo source tại đây https://github.com/hieudt/laravel-vuejs-handle-error/tree/framgia/spa
Các phần sau mình sẽ hướng dẫn các bạn làm chức năng đăng nhập xác thực bằng Laravel Passport
Chào thân ái !!!