本教程是作者自己在学习Laravel和Vue时的一些总结,有问题欢迎指正。
Laravel是PHP的一个框架,Vue是前端页面的框架,这两个框架如何结合起来构建一个SPA(Single Page Application)呢?流程大致分为下面三步:
页面请求Laravel的一个路由
路由返回渲染一个包含了Vue的SPA框架
在上面渲染出来的框架中使用Vue来加载不同的页面单元模块
主要会学习使用到三个东西:
laravel
vue.js
Vue-router
axios

上面是一个简单的流程图,从图中我们可以看到,当请求3
和4
的路由时,并不会再次请求后端的Laravel,而是前端渲染了。
说了这么多,我们开始写代码吧~
1. 安装 1 2 3 4 5 6 composer create-project --prefer-dist laravel/ laravel laravel-spa "5.6.*" cd laravel-spa npm install npm install vue-router
安装好laravel
和vue-router
后,我们需要配置前端路由和路由对应的组件
2. 配置Vue Router 在Vue Router
中把route
和vue组件做了一个映射,在渲染时会把不同的组件渲染到<router-view></router-view>
标签中。
首先,我们修改resources/assets/js/app.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 33 34 35 36 37 window .Vue = require ('vue' );import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) import App from './views/App' import Hello from './views/Hello' import Home from './views/Home' const router = new VueRouter({ mode: 'history' , base: '/spa' , routes: [ { path: '/' , name: 'home' , component: Home }, { path: '/hello' , name: 'hello' , component: Hello } ], }); const app = new Vue({ el: '#app' , components: { App, }, router });
然后,新建以下几个文件:
1 2 3 4 mkdir resources/assets/ js/views touch resources/assets/ js/views/ App.vue touch resources/assets/ js/views/ Home.vue touch resources/assets/ js/views/ Hello.vue
App.vue
是所有组件的父组件,负责渲染其他页面,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <template > <div > <h1 > Vue Router Demo App</h1 > <p > <router-link :to =" { name: 'home' } " > Home</router-link > | <router-link :to =" { name: 'hello' } " > Hello World</router-link > | </p > <div class ="container" > <router-view > </router-view > </div > </div > </template > <script > export default {} </script >
注意这个router-view
标签,Vue Router
会将组件渲染到该标签里面。其他几个页面就是我们需要展示的组件页面了。
Home.vue :
1 2 3 <template > <p > This is the homepage</p > </template >
Hello.vue :
1 2 3 <template > <p > Hello World!</p > </template >
现在的目录结构是把页面的模版和组件模版放在同一个目录里面的,为了方便管理,我们可以把重用的组件单独放一个component
目录里。
3. 后端代码 SPA
应用主要是以接口的形式请求的,后端在接收到页面请求时不需要做过多的处理,代码也很简单,routes/web.php
修改如下,删除了原来的/
路由:
创建一个SpaController
:
1 php artisan make :controller SpaController
在SpaConrtoller
的index
方法中我们直接返回需要渲染的模版:
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php namespace App \Http \Controllers ;use Illuminate \Http \Request ;class SpaController extends Controller { public function index () { return view('spa' ); } }
最后,编辑resources/views/spa.blade.php
模版:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE html> <html > <head > <meta charset ="utf-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <title > Laravel Vue SPA Demo</title > <meta name ="viewport" content ="width=device-width, initial-scale=1" > <meta name ="csrf-token" content =" {{ csrf_token() }} " ></head > <body > <div id ="app" > <app > </app > </div > </body > <script src =" {{ mix('js/app.js') }} " ></script > </html >
基本完成,现在来看看效果,因为laravel已经集成了一些前端开发的脚手架,可以说非常友好了,所以在写好前端的组件后,运行如下命令就能打包前端代码了:

现在我们简单的SPA静态页面已经搭建完成了,可以看到当切换URL时,整个页面的主题和菜单并没有换,更新的只是下面的内容,接下来我们是这调用后端的API。
4. 编写一个测试API 由于是测试,后端代码很简单,就几行,routes/api.php
修改如下:
1 2 3 Route::get('/users' , function () { return factory('App\User' , 10 )->make(); });
上面就是我们编写的一个简单接口,我么直接在路由中使用了Laravel现成的User
模型mock
10条数据,注意,由于Laravel中web
和api
是单独分开的,所以在访问api
接口时需要加上/api
前缀,分析App\Providers
\RouteServiceProvider
文件就能看出来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 protected function mapApiRoutes (){ Route ::prefix ('api' ) ->middleware ('api' ) ->namespace ($this->namespace) ->group (base_path('routes/api.php' )); }
我们试着访问下接口:
接口写好,现在我们需要在前端用axios
调用我们的接口。
5. axios上手 现在回到我们Vue Router
的配置中,添加一个组件并定义一个新的路由:
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 … import UsersIndex from './views/UsersIndex'… const router = new VueRouter({ mode: 'history' , base: '/' , routes: [ { path : '/' , name : 'home' , component: Home }, { path : '/hello' , name : 'hello' , component: Hello }, { path : '/users' , name : 'users.index' , component: UsersIndex } ], });
实现UsersIndex组件:
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 <template > <div class ="users" > <div v-if ="loading" class ="loading" > Loading</div > <div v-if ="error" class ="error" > <p > {{ error }} </p > <p > <button @click.prevent ="fetchData" > Try again</button > </p > </div > <ul v-if ="users" > <li v-for ="{name, email} in users" @key ="name" > <strong > Name: </strong > {{ name }} , <strong > Email: </strong > {{ email }} </li > </ul > </div > </template > <script > import axios from 'axios'; export default { data() { return { loading: false, users: null, error: null, }; }, created() { this.fetchData() }, methods: { fetchData() { this.error = this.users = null; this.loading = true; axios.get('/api/users') .then(response => { this.loading = false; this.users = response.data; }) .catch(error => { this.loading = false; this.error = error.response.data.message || error.message; }) } } } </script >
这个Vue的组件很简单,说说fetchData
这个方法,使用了axios
来get
我们写好的后端接口,将得到的数据用Vue在前端渲染出来,看看效果:
我们成功获取到了后端数据,并在前端渲染出来。到此,我们现在已经了解了开发SPA应用的简单流程。
6. 最后再来个总结吧 使用SPA有什么好处呢?第一,不同页面之前切换时不会有明显的变化,至少整个页面框架不会切换,前端再配合一个loading
动画,会更加友好,而全部用服务端渲染,页面在切换时会有一段时间的页面空白现象,在网速不理想的情况下空白的时间会更长。第二,职责更加清晰,SPA应用完全是前后端分离,后端只需要认真编写接口,前端只要获取并渲染,开发人员不需要同时看后端代码和前端代码,职责清晰的同时保证了码代码的效率,第三,SPA
是无状态的,不需要管理session
。
参考 :https://laravel-news.com/using-vue-router-laravel https://router.vuejs.org/zh/
欢迎阅读本篇文章,如有兴趣可以关注博主公众号哦: