美文网首页小白学编程
使用Laravel 和 Vue 构建一个简单的SPA

使用Laravel 和 Vue 构建一个简单的SPA

作者: 正义的程序员 | 来源:发表于2019-10-04 15:15 被阅读0次

    本教程是作者自己在学习Laravel和Vue时的一些总结,有问题欢迎指正。

    Laravel是PHP的一个框架,Vue是前端页面的框架,这两个框架如何结合起来构建一个SPA(Single Page Application)呢?流程大致分为下面三步:

    1. 页面请求Laravel的一个路由
    2. 路由返回渲染一个包含了Vue的SPA框架
    3. 在上面渲染出来的框架中使用Vue来加载不同的页面单元模块

    主要会学习使用到三个东西:

    1. laravel
    2. vue.js
    3. Vue-router
    4. axios

    上面是一个简单的流程图,从图中我们可以看到,当请求34的路由时,并不会再次请求后端的Laravel,而是前端渲染了。

    说了这么多,我们开始写代码吧~

    1. 安装

    composer create-project --prefer-dist laravel/laravel laravel-spa "5.6.*"
    cd laravel-spa
    
    npm install
    npm install vue-router
    

    安装好laravelvue-router后,我们需要配置前端路由和路由对应的组件

    2. 配置Vue Router

    Vue Router中把route和vue组件做了一个映射,在渲染时会把不同的组件渲染到<router-view></router-view>标签中。

    首先,我们修改resources/assets/js/app.js这个文件:

    window.Vue = require('vue');
    // 或者
    import Vue from 'vue'
    
    import VueRouter from 'vue-router'
    // 引入Vue Router并加载到Vue中
    Vue.use(VueRouter)
    
    // 引入我们要使用到的几个组件
    import App from './views/App'
    import Hello from './views/Hello'
    import Home from './views/Home'
    
    // 实例化一个Vue Router
    const router = new VueRouter({
        mode: 'history',
        base: '/spa',
        routes: [
            {
                path: '/',  // 这是路径
                name: 'home',   // 这是名称
                component: Home // 这是使用的组件
            },
            {
                path: '/hello',
                name: 'hello',
                component: Hello
            }
        ],
    });
    
    // 注入Vue Router 实例,我们就能在vue里面这样使用: this.$router, this.$route
    const app = new Vue({
        el: '#app',
        components: { App, },
        router 
    });
    

    然后,新建以下几个文件:

    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是所有组件的父组件,负责渲染其他页面,代码如下:

    <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 :

    <template>
      <p>This is the homepage</p>
    </template>
    

    Hello.vue :

    <template>
        <p>Hello World!</p>
    </template>
    

    现在的目录结构是把页面的模版和组件模版放在同一个目录里面的,为了方便管理,我们可以把重用的组件单独放一个component目录里。

    3. 后端代码

    SPA应用主要是以接口的形式请求的,后端在接收到页面请求时不需要做过多的处理,代码也很简单,routes/web.php修改如下,删除了原来的/路由:

    Route::get('/{any}', 'SpaController@index')->where('any', '.*');
    

    创建一个SpaController

    php artisan make:controller SpaController
    

    SpaConrtollerindex方法中我们直接返回需要渲染的模版:

    <?php
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class SpaController extends Controller
    {
        public function index()
        {
            return view('spa');
        }
    }
    
    

    最后,编辑resources/views/spa.blade.php模版:

    <!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已经集成了一些前端开发的脚手架,可以说非常友好了,所以在写好前端的组件后,运行如下命令就能打包前端代码了:

    npm run watch
    

    现在我们简单的SPA静态页面已经搭建完成了,可以看到当切换URL时,整个页面的主题和菜单并没有换,更新的只是下面的内容,接下来我们是这调用后端的API。

    4. 编写一个测试API

    由于是测试,后端代码很简单,就几行,routes/api.php修改如下:

    Route::get('/users', function () {
        return factory('App\User', 10)->make();
    });
    

    上面就是我们编写的一个简单接口,我么直接在路由中使用了Laravel现成的User模型mock10条数据,注意,由于Laravel中webapi是单独分开的,所以在访问api接口时需要加上/api前缀,分析`App\Providers

    \RouteServiceProvider`文件就能看出来:

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php'));
    }
    

    我们试着访问下接口:


    接口写好,现在我们需要在前端用axios调用我们的接口。

    5. axios上手

    现在回到我们Vue Router的配置中,添加一个组件并定义一个新的路由:

    …
    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组件:

    <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这个方法,使用了axiosget我们写好的后端接口,将得到的数据用Vue在前端渲染出来,看看效果:

    我们成功获取到了后端数据,并在前端渲染出来。到此,我们现在已经了解了开发SPA应用的简单流程。

    6. 最后再来个总结吧

    使用SPA有什么好处呢?第一,不同页面之前切换时不会有明显的变化,至少整个页面框架不会切换,前端再配合一个loading动画,会更加友好,而全部用服务端渲染,页面在切换时会有一段时间的页面空白现象,在网速不理想的情况下空白的时间会更长。第二,职责更加清晰,SPA应用完全是前后端分离,后端只需要认真编写接口,前端只要获取并渲染,开发人员不需要同时看后端代码和前端代码,职责清晰的同时保证了码代码的效率,第三,SPA是无状态的,不需要管理session

    参考 :
    https://laravel-news.com/using-vue-router-laravel
    https://router.vuejs.org/zh/


    👏文章首发【正义的程序猿】,欢迎大家关注哦

    相关文章

      网友评论

        本文标题:使用Laravel 和 Vue 构建一个简单的SPA

        本文链接:https://www.haomeiwen.com/subject/ihhspctx.html