使用 Laravel 构建 Vue SPA 第 5 部分
发布于 作者: Paul Redmond
在第 4 部分中,我们最后学习了如何编辑用户,并了解了如何使用 v-model
来跟踪对视图组件 user
属性的更改。现在我们准备查看如何删除用户以及如何在删除操作成功后处理 UI。
在此过程中,我们将学习构建一个 Axios 客户端实例,以增强我们配置 API 客户端的灵活性。
更新 API 以处理用户删除
我们要做的第一件事是定义用于删除单个用户的 API 路由。由于路由模型绑定,这只需要在 UsersController
中添加几行代码。
public function destroy(User $user){ $user->delete(); return response(null, 204);}
接下来,在 routes/api.php
文件中 Api 组的底部定义新的路由。
Route::namespace('Api')->group(function () { Route::get('/users', 'UsersController@index'); Route::get('/users/{user}', 'UsersController@show'); Route::put('/users/{user}', 'UsersController@update'); Route::delete('/users/{user}', 'UsersController@destroy');});
在前端删除用户
我们将在 /users/:id/edit
视图组件中添加删除功能,方法是在 UsersEdit.vue
组件的“更新”按钮下方添加一个删除按钮。
<div class="form-group"> <button type="submit" :disabled="saving">Update</button> <button :disabled="saving" @click.prevent="onDelete($event)">Delete</button></div>
我们从更新按钮中复制了 :disabled
属性,可以使用它来防止在执行操作时意外更新或删除。
接下来,我们需要将 onDelete()
回调与处理用户删除的操作关联起来。
onDelete() { this.saving = true; api.delete(this.user.id) .then((response) => { console.log(response); });}
我们在 API 客户端上调用 delete()
函数,然后链接一个回调以在控制台中记录响应对象。如果单击“删除”,更新和删除按钮将被禁用,因为我们设置了 this.saving = true
- 我们将在稍后回到这一点。如果打开了控制台,您将看到一个 204 No Content
响应对象,指示删除成功。
如何对成功删除的用户做出反应
与更新用户略有不同的是,删除记录后,数据库中不再存在用户。在传统的 Web 应用程序中,我们可能会删除记录,然后将用户重定向回所有用户的列表。
我们可以在 SPA 中通过以编程方式将用户导航回 /users
页面来实现这一点。
this.$router.push({ name: 'users.index' })
将 this.$router.push()
调用应用于我们的事件,最基本的形式如下所示。
onDelete() { this.saving = true; api.delete(this.user.id) .then((response) => { this.$router.push({ name: 'users.index' }); });}
如果您刷新应用程序并删除用户,您将注意到禁用按钮会短暂闪烁,然后浏览器会导航到 /users
页面,没有任何反馈。
我们可以使用专用的 toast/通知机制来处理用户通知。我会将方法留给您,但以下是有关我的想法的基本思路。
onDelete() { this.saving = true; api.delete(this.user.id) .then((response) => { this.message = 'User Deleted'; setTimeout(() => this.$router.push({ name: 'users.index' }), 2000); });}
上面的代码设置了我们在第 4 部分中设置的 this.message
数据属性,并在两秒钟后导航到 /users
索引页面。
您还可以使用类似 portal-vue 的东西或布局中的组件,该组件会暂时(或带有一个强制关闭按钮)闪烁消息,以指示操作已成功(或失败),从而为用户提供一些反馈。
404
您可能已经注意到,如果我们的 Vue 路由与模式 /users/:id/edit
匹配,但如果找不到用户 ID,我们仍然可能会从 API 中获得 404
响应。
在服务器端 Laravel 应用程序中,我们可以轻松地从 ModelNotFoundException
渲染 404.blade.php
。然而,SPA 有点不同。上面的路由是有效的,因此我们需要我们的组件要么渲染错误组件,要么将用户重定向到专用的 404 路由。
我们将在 resources/assets/js/app.js
中的 Vue 路由器配置中添加一些新的路由,这些路由将使用专用的 404 视图和一个通配符组件,该组件会将不匹配的路由重定向到 404 路由。
{ path: '/404', name: '404', component: NotFound },{ path: '*', redirect: '/404' },
我们将在 resources/assets/js/views/NotFound.vue
中创建一个简单的 NotFound
组件。
<template> <div> <h2>Not Found</h2> <p>Woops! Looks like the page you requested cannot be found.</p> </div></template>
由于我们在 Laravel 后端有一个通配符路由,这意味着前端也需要一个通配符路由,以便在路径与定义的路由不匹配时使用 404 页面进行响应。以下是对捕捉所有路由并发送渲染 SPA 模板的后端路由的回顾。
Route::get('/{any}', 'SpaController@index') ->where('any', '.*');
如果您输入一个无效的 URL,例如 /does-not-exist
,您将看到类似以下内容。
Vue 路由器会命中通配符路由,该路由会将浏览器重定向到 /404
。
我们之前使用无效用户 ID 的示例仍然无法正常工作,因为从技术上讲该路由是有效的。我们需要更新 UsersEdit
组件,以便在 create()
回调中捕捉失败的请求并将用户发送到 404 路由。
created() { api.find(this.$route.params.id) .then((response) => { this.loaded = true; this.user = response.data.data; }) .catch((err) => { this.$router.push({ name: '404' }); });}
现在,如果您直接向像 /users/2000/edit
这样的 URI 发出请求,您应该会看到应用程序重定向到 404 页面,而不是在 UsersEdit
组件中挂起在“正在加载...”UI 上。
API 客户端选项
虽然我们的专用 users.js
HTTP 客户端可能在小型应用程序中被认为是过度的,但我认为这种分离已经为我们很好地服务,因为我们在多个组件中使用了 API 模块。如果您想了解灵活客户端所提供的所有细节,我将在我的文章 构建灵活的 Axios 客户端 中详细讨论这个想法。
无需更改客户端的外部 API,我们就可以更改客户端在幕后的工作方式。例如,我们可以创建一个具有可自定义配置和默认值的 Axios 客户端实例。
import axios from 'axios'; const client = axios.create({ baseURL: '/api',}); export default { all(params) { return client.get('users', params); }, find(id) { return client.get(`users/${id}`); }, update(id, data) { return client.put(`users/${id}`, data); }, delete(id) { return client.delete(`users/${id}`); },};
现在,如果以后想要自定义整个模块的工作方式,我可以使用一些配置来替换 baseURL,而不会影响方法。
下一步
我们学习了如何删除用户以及如何在前端通过 Vue 路由器响应成功的删除操作。我们通过在主 app.js
文件中使用 Vue.use(VueRouter)
将 Vue 路由器注册到应用程序,引入了通过 this.$router
属性进行的以编程方式的导航。
接下来,我们将着手构建用户创建,以完成学习如何执行基本的创建、读取、更新和删除 (CRUD) 操作。在这一点上,您应该已经拥有完成新用户创建所需的所有工具,因此请随时尝试在发布本系列下一篇文章之前构建此功能。
准备好了后,请查看 第 6 部分 - 创建新用户