Create a single-page Vue application from Laravel


In this tutorial, we continue to create a Vue Single Page Application (SPA) in Laravel by learning how to load asynchronous data from the Laravel API in the Vue component.We'll also look at error handling, such as how the interface responds when the API returns an error.

If you haven't studied Part One , we build a Vue Single Page Application (SPA) from the Vue Router and Laravel backends.If you want to keep up with your studies, you should first go to the first part in a complete way!

Keeping the server-side data simple, our API will return false data.In the third section, we'll have the API return test data from the database through the controller.

API Routing

Vue single-page applications are stateless, which requires us to initiate API requests to Laravel routes by defining routes in routes/api.php.API routing does not use session state, indicating that the application is truly stateless on the back end.

In the example, suppose we need a list of users to demonstrate starting an asynchronous request from a Vue application to the back end:

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

Our temporary routing uses Model Factory To create an Eloquent model collection that has not been saved to the database.Using the make() method, test data is not saved to the database; instead, it returns a new App\User instance that has not been saved to the database.

Defining a route in routes/api.php means that requests will all have a/api prefix, since this prefix is defined in the applied RouteServiceProvider class:

protected function mapApiRoutes()
{
    Route::prefix('api')
         ->middleware('api')
         ->namespace($this->namespace)
         ->group(base_path('routes/api.php'));
}

The result is GET/api/users, and the example looks like this:

[
   {
      "name":"Roel Rosenbaum I",
      "email":"catharine.kreiger@example.net"
   },
   {
      "name":"Prof. Clarissa Osinski",
      "email":"wilfrid.kiehn@example.com"
   },
   {
      "name":"Myrtle Wyman",
      "email":"dan31@example.com"
   },
   ...
]

Client Routing

In the first section, we created several new routes in resources/assets/js/app.js to demonstrate SPA navigation.Any time you want to add a new route, we can create a new object in the routes array that defines the path, name, and components.The last route is the newly created /users route:

import UsersIndex from './views/UsersIndex';

const router = new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/hello',
            name: 'hello',
            component: Hello,
        },
        {
            path: '/users',
            name: 'users.index',
            component: UsersIndex,
        },
    ],
});

UsersIndex Component

There is a route that uses the UsersIndex component; currently we want it (located in resources/assets/js/views/UsersIndex.vue) to look like this:

<template>
    <div class="users">
        <div class="loading" v-if="loading">
            Loading...
        </div>

        <div v-if="error" class="error">
            {{ error }}
        </div>

        <ul v-if="users">
            <li v-for="{ name, email } in users">
                <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 => {
                    console.log(response);
                });
        }
    }
}
</script>

If you are new to Vue, you may encounter some unfamiliar concepts.Suggest reading Vue assembly Documentation to familiarize yourself with Vue's life cycle hooks (new, loaded, etc.).

In this component, asynchronous data is obtained when the component is created.Define a fechData() method to initialize the error and users properties to null and set load to true.

Use of the last line in the fetchData() method Axios The library makes an HTTP request to the Laravel API.Axios is a promise-based HTTP client that records returns through a chain call to then() callback and assigns the final value to the users data property.

Here's what console data looks like when /users (client pages, not API s) are loaded into the application:

Another thing you want to be aware of is deconstruction , as follows:

<li v-for="{ name, email } in users">
    <strong>Name:</strong> {{ name }},
    <strong>Email:</strong> {{ email }}
</li>

Deconstruction is an effective way to extract props for an object and is concise/understandable.

Complete Routing Component

Now that we have a /users component and a route, let's create a navigation link to the App component that points to users to set user data:

In resources/assets/js/views/App.vue, add a link to the user's route:

<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> |
            <router-link :to="{ name: 'users.index' }">Users</router-link>
        </p>

        <div class="container">
            <router-view></router-view>
        </div>
    </div>
</template>
<script>
    export default {}
</script>

Next, let's update the UsersIndex.vue file to set user data:

fetchData() {
    this.error = this.users = null;
    this.loading = true;
    axios
        .get('/api/users')
        .then(response => {
            this.loading = false;
            this.users = response.data;
        });
}

Now, if you refresh the page, you should see something like the following:

error handling

Components usually run as expected, but we haven't handled API errors yet.We simulated a server-side error in the API:

Route::get('/users', function () {
    if (rand(1, 10) < 3) {
        abort(500, 'We could not retrieve the users');
    }

    return factory('App\User', 10)->make();
});

Use rand() to terminate the request when its value is less than 3.If you refresh the page a few times, you may see "Loading..."If you examine the developer tools, you will find an error in an Axios request that was not captured:

We can handle this failed request by calling catch() chained on Axios prpmise:

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;
        });
}

Set the loading property value to false, and use the error exception of the response to set the message.This error message is returned to the exception.message property.

For a good user experience, under this condition, we set a "try again" button in the UsersIndex.vue template, which simply calls the fetchData method to refresh the users properties:

<div v-if="error" class="error">
    <p>{{ error }}</p>

    <p>
        <button @click.prevent="fetchData">
            Try Again
        </button>
    </p>
</div>

Now if it fails, the UI should look like this:

summary

In this short article, we've added a new route to get some fake users from the stateless Laravel API.We use Rear Navigation to get data specifically.Or you can use other methods, such as getting it from the API when the component is created.

In Part Three Let's try to use a callback in the Vue Router to get the number so you can see how to get the data before rendering the router view before navigating to the component.

We also convert the API to get data from the initialized database tables, so we can navigate to a specific user by setting routing parameters.

Now, let's take a look at creating a single-page Vue app from Laravel. Part Three !

Keywords: PHP Vue axios Laravel Database

Added by alsinha on Tue, 24 Sep 2019 05:43:15 +0300