使用 Laravel 构建 Vue SPA 应用 - 第二部分

发布于 作者

Building a Vue SPA with Laravel Part 2 image

在本教程中,我们将继续使用 Laravel 构建 Vue 单页应用程序 (SPA),学习如何在 Vue 组件中从 Laravel API 端点加载异步数据。我们还将探讨 API 响应返回错误时的错误处理以及如何在界面中进行响应。

如果你没有阅读 第一部分,我们介绍了使用 Vue 路由器和 Laravel 后端连接 Vue 单页应用程序 (SPA)。如果你想跟着做,你应该先阅读第一部分!

为了使服务器端数据保持简单,我们的 API 将使用假数据。在第三部分,我们将把 API 转换为控制器,测试数据将来自数据库。

API 路由

Vue SPA 应用程序是无状态的,这意味着我们向 Laravel 路由器发出 API 请求,我们的路由定义在 routes/api.php 中。API 路由不使用会话状态,这意味着我们的应用程序在后端确实是无状态的。

在我们的示例中,假设我们想要获取一个用户列表,以便我们可以演示从我们的 Vue 应用程序到后端的异步请求。

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

我们的临时路由正在使用 模型工厂 来创建尚未持久保存到数据库的 Eloquent 模型集合。我们使用 make() 方法,该方法不会尝试将测试数据插入到数据库中,而是返回一个尚未持久保存的新 App\User 实例的集合。

routes/api.php 文件中定义路由意味着我们的请求有一个 /api 的前缀,这是因为应用程序的 RouteServiceProvider 类中定义了这个前缀。

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

我们的用户资源是 GET /api/users,一个示例响应可能如下所示:

[
{
"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"
},
...
]

客户端路由

如果你按照第一部分进行操作,我们在 resources/assets/js/app.js 文件中构建了几个路由来演示在 SPA 中进行导航。每当我们想要添加一个新的路由时,我们都会在 routes 数组中创建一个新对象,这个对象定义了每个路由的路径、名称和组件。最后一个路由是我们的新 /users 路由。

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

路由使用 UsersIndex 组件定义了一个路由;以下是该文件(位于 resources/assets/js/views/UsersIndex.vue)的样子:

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

如果你不熟悉 Vue,这里可能有一些你不熟悉的概念。我建议阅读 Vue 组件 文档,并熟悉 Vue 生命周期钩子(created、mounted 等)。

在这个组件中,我们是在组件 created 钩子期间获取异步数据的。我们定义了一个 fechData() 方法,它将错误和用户属性重置为 null,将 loading 设置为 true。

fetchData() 方法中的最后一行使用 Axios 库向我们的 Laravel API 发出 HTTP 请求。Axios 是一个基于 promise 的 HTTP 客户端,我们使用它来链接 then() 回调,我们将在其中记录响应,并最终将其设置为 users 数据属性。

以下是在应用程序中加载 /users 时控制台数据的样子(客户端页面,而不是 API):

我还想让你注意这里正在进行的 对象解构

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

对象解构是一种有效的方式,它只获取对象所需的内容,更简洁/可读。

完成路由组件

我们已经有了 /users 的路由和组件,让我们在主 App 组件中添加一个导航链接,然后设置 users 响应中的用户数据。

resources/assets/js/views/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> |
<router-link :to="{ name: 'users.index' }">Users</router-link>
</p>
 
<div class="container">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {}
</script>

接下来,让我们更新 UsersIndex.vue 文件来设置用户数据。

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

现在,如果你刷新页面,你应该看到如下内容:

处理错误

我们的组件在大多数情况下应该按预期工作,但我们还没有处理 API 错误。让我们在 API 端点中添加一个模拟服务器错误。

Route::get('/users', function () {
if (rand(1, 10) < 3) {
abort(500, 'We could not retrieve the users');
}
 
return factory('App\User', 10)->make();
});

我们使用 rand() 来在数字小于 3 时中止请求。如果你刷新页面几次,你应该会看到“加载中...”,并且如果你检查开发工具,你将看到 Axios 请求发出的未捕获异常。

我们可以通过在 Axios promise 上链接 catch() 回调来处理失败的请求。

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

我们将加载数据属性设置为 false,并使用错误异常来尝试设置来自响应的 message 键。如果找不到 message 键,则会回退到 exception.message 属性。

为了保险起见,让我们在 UsersIndex.vue 模板中为用户提供一个“重试”按钮,该按钮会简单地调用我们的 fetchData 方法来刷新 users 属性。

<div v-if="error" class="error">
<p>{{ error }}</p>
 
<p>
<button @click.prevent="fetchData">
Try Again
</button>
</p>
</div>

现在,如果出现故障,UI 应该如下所示:

结论

在这篇简短的文章中,我们添加了一条新路由,用于从无状态 Laravel API 端点列出一些虚拟用户。我们使用了“导航后”数据获取策略来获取数据。或者换句话说,我们在创建组件时向 API 请求数据。

第三部分,我们将探讨在 Vue 路由器中使用回调在导航到组件之前获取数据,向你展示如何在渲染路由视图之前获取数据。

我们还将把 API 转换为使用具有种子数据的数据库表,这样我们就可以继续导航到单个用户,这涵盖了使用路由参数。

现在,让我们继续学习使用 Laravel 构建 Vue SPA 应用的 第三部分

Paul Redmond photo

Laravel News 的特约撰稿人。全栈 web 开发人员和作者。

Cube

Laravel 新闻通讯

加入 40,000 多名其他开发者,永远不要错过新的提示、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理你的服务器,并在几秒钟内部署你的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动补全和本地和生产环境的即时反馈进行调试。

Tinkerwell
No Compromises logo

不妥协

Joel 和 Aaron,来自 No Compromises 播客的两位经验丰富的开发者,现在可以为你的 Laravel 项目聘用。 ⬧ 固定费率 7,500 美元/月。 ⬧ 没有冗长的销售流程。 ⬧ 没有合同。 ⬧ 100% 退款保证。

不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,以确保你的 web 应用程序成功。

Kirschbaum
Shift logo

Shift

正在使用旧版本的 Laravel? 立即进行自动化的 Laravel 升级和代码现代化,让您的应用程序保持新鲜。

Shift

Bacancy logo

Bacancy

仅需每月 2500 美元,即可用一位拥有 4-6 年经验的资深 Laravel 开发者来为您的项目增效。 获取 160 小时的专业知识和 15 天的无风险试用。立即预约电话!

Bacancy
Lucky Media logo

Lucky Media

立即获得 Lucky - Laravel 开发的理想选择,拥有十多年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel 电子商务

Laravel 的电子商务。一个开源包,将现代无头电子商务功能的强大功能带入 Laravel。

Lunar: Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 职位板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS 启动工具包

SaaSykit 是一个 Laravel SaaS 启动工具包,它包含运行现代 SaaS 所需的所有功能。 支付、漂亮的结帐、管理面板、用户仪表板、身份验证、现成的组件、统计信息、博客、文档等等。

SaaSykit: Laravel SaaS 启动工具包
Rector logo

Rector

您无缝 Laravel 升级的合作伙伴,降低成本,加快创新,帮助企业取得成功

Rector
MongoDB logo

MongoDB

通过 MongoDB 和 Laravel 的强大集成来增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。 在使用熟悉的 Eloquent API 的同时,支持事务、搜索、分析和移动用例。 了解 MongoDB 的灵活、现代数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的零依赖输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel Prompts 构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包向您的 Laravel 应用程序添加评论

阅读文章