使用 Laravel 构建 Vue SPA 第 6 部分
发布于 作者: Paul Redmond
我们将完成基本 CRUD 的最后一部分:创建新用户。您拥有迄今为止涵盖的所有主题中所需的所有工具,因此请随时尝试创建用户并将本文与您的工作进行比较。
如果您需要赶上来,我们在 第 5 部分 中完成了删除用户的功能,以及如何在成功删除后重定向用户。我们还研究了将我们的 HTTP 客户端提取到一个专用模块中,以便在整个应用程序中重复使用。提醒一下,本教程并不专注于权限;我们正在使用内置的 Laravel 用户表来演示在 Vue Router 项目的上下文中使用 CRUD。
以下是迄今为止的系列概述
- 设置项目和 Vue 路由器 - 第 1 部分
- 在 Vue 路由器中加载异步数据 - 第 2 部分
- 在 Laravel 中添加真正的 API 端点 - 第 3 部分
- 编辑现有用户 - 第 4 部分
- 删除用户 - 第 5 部分
添加创建用户组件
首先,我们将创建和配置用于创建新用户的前端组件。UsersCreate.vue
组件类似于我们在 第 4 部分 中创建的 UsersEdit.vue
组件
<template> <div> <h1>Create a User</h1> <div v-if="message" class="alert">{{ message }}</div> <form @submit.prevent="onSubmit($event)"> <div class="form-group"> <label for="user_name">Name</label> <input id="user_name" v-model="user.name" /> </div> <div class="form-group"> <label for="user_email">Email</label> <input id="user_email" type="email" v-model="user.email" /> </div> <div class="form-group"> <label for="user_password">Password</label> <input id="user_password" type="password" v-model="user.password" /> </div> <div class="form-group"> <button type="submit" :disabled="saving"> {{ saving ? 'Creating...' : 'Create' }} </button> </div> </form> </div></template><script> import api from '../api/users'; export default { data() { return { saving: false, message: false, user: { name: '', email: '', password: '', } } }, methods: { onSubmit($event) { this.saving = true this.message = false } } }</script><style lang="scss" scoped>$red: lighten(red, 30%);$darkRed: darken($red, 50%); .form-group { margin-bottom: 1em; label { display: block; }}.alert { background: $red; color: $darkRed; padding: 1rem; margin-bottom: 1rem; width: 50%; border: 1px solid $darkRed; border-radius: 5px;}</style>
我们添加了表单和输入,并对 onSubmit
方法进行了占位符。组件的其余部分与 UsersEdit
组件相同,除了添加了 password
输入。创建新用户需要密码。我们在编辑用户时跳过了密码字段,因为通常您有一个与编辑用户分开的特定密码更改流程。
请注意,我们可以花一些时间将创建和编辑视图中的表单提取到一个专用组件中,但我们将把它留到以后再做(或者您可以独立完成)。唯一的区别是使用现有用户数据(包括用户 ID)填充表单与使用空表单创建用户。
配置路由
接下来,我们需要配置 Vue 路由并链接到页面,以便我们可以导航到用户创建屏幕。打开 resources/assets/js/app.js
文件并添加以下路由(和导入)
import UsersCreate from './views/UsersCreate'; // ... const router = new VueRouter({ mode: 'history', routes: [ // ... { path: '/users/create', name: 'users.create', component: UsersCreate, }, { path: '/404', name: '404', component: NotFound }, { path: '*', redirect: '/404' }, ],});
接下来,让我们在 assets/js/views/UsersIndex.vue
组件中添加指向新组件的链接
<template> <div class="users"> <!-- ... --> <div> <router-link :to="{ name: 'users.create' }">Add User</router-link> </div> </div></template>
您现在应该能够使用 yarn watch
重新编译您的前端资产,并看到以下内容
提交表单
此时,我们没有后端路由,因此通过 API 客户端提交表单将返回 405 Method Not Allowed
。让我们在 UsersCreate
组件中连接 onSubmit()
处理程序,而无需定义路由,这将使我们能够快速查看提交表单的错误状态
methods: { onSubmit($event) { this.saving = true this.message = false api.create(this.user) .then((data) => { console.log(data); }) .catch((e) => { this.message = e.response.data.message || 'There was an issue creating the user.'; }) .then(() => this.saving = false) }}
我们的表单在此时记录了响应数据,捕获错误,最后切换 saving = false
以隐藏“正在保存”状态。我们尝试从响应中读取 message
属性,或者提供默认错误消息。
接下来,我们需要在位于 resources/assets/js/api/users.js
的组件中导入的 API 模块中添加 create()
方法
export default { // ... create(data) { return client.post('users', data); }, // ...};
表单将通过客户端向 UsersController
发送一个 POST
请求。如果您提交表单,您将在控制台中看到一个带有 405
响应错误的错误消息
添加 API 端点
我们准备在 Laravel 中添加 API 端点来创建新用户。它将类似于编辑现有用户。但是,此响应将返回 201 Created
状态代码。
我们将从通过 API 定义存储新用户的路由开始
// routes/api.phpRoute::namespace('Api')->group(function () { // ... Route::post('/users', 'UsersController@store');});
接下来,打开 app/Http/Controllers/UsersController.php
文件并添加 store()
方法
public function store(Request $request){ $data = $request->validate([ 'name' => 'required', 'email' => 'required|unique:users', 'password' => 'required|min:8', ]); return new UserResource(User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => bcrypt($data['password']), ]));}
当用户有效时,您提交表单后,新用户响应类似于以下内容
{ "data": { "id":51, "name":"Paul Redmond", "email":"[email protected]" }}
如果您提交了无效数据,您将收到类似以下消息的内容
处理成功
我们已经处理了服务器错误或验证错误的情况;让我们通过处理成功创建用户来完成。我们将清除表单并重定向到用户的编辑页面
onSubmit($event) { this.saving = true this.message = false api.create(this.user) .then((response) => { this.$router.push({ name: 'users.edit', params: { id: response.data.data.id } }); }) .catch((e) => { this.message = e.response.data.message || 'There was an issue creating the user.'; }) .then(() => this.saving = false)}
以下是最终的 UsersCreate.vue
组件
<template> <div> <h1>Create a User</h1> <div v-if="message" class="alert">{{ message }}</div> <form @submit.prevent="onSubmit($event)"> <div class="form-group"> <label for="user_name">Name</label> <input id="user_name" v-model="user.name" /> </div> <div class="form-group"> <label for="user_email">Email</label> <input id="user_email" type="email" v-model="user.email" /> </div> <div class="form-group"> <label for="user_password">Password</label> <input id="user_password" type="password" v-model="user.password" /> </div> <div class="form-group"> <button type="submit" :disabled="saving"> {{ saving ? 'Creating...' : 'Create' }} </button> </div> </form> </div></template><script> import api from '../api/users'; export default { data() { return { saving: false, message: false, user: { name: '', email: '', password: '', } } }, methods: { onSubmit($event) { this.saving = true this.message = false api.create(this.user) .then((response) => { this.$router.push({ name: 'users.edit', params: { id: response.data.data.id } }); }) .catch((e) => { this.message = e.response.data.message || 'There was an issue creating the user.'; }) .then(() => this.saving = false) } } }</script><style lang="scss" scoped>$red: lighten(red, 30%);$darkRed: darken($red, 50%); .form-group { margin-bottom: 1em; label { display: block; }}.alert { background: $red; color: $darkRed; padding: 1rem; margin-bottom: 1rem; width: 50%; border: 1px solid $darkRed; border-radius: 5px;}</style>
结论
我们有一个基本的工作表单来创建新用户,该表单只有基本的验证逻辑。本教程将引导您完成在 Vue 中执行 CRUD 的基本操作。
作为作业,您可以为渲染用于创建新用户和编辑现有用户的表单定义一个专用用户表单组件,如果您认为它有价值的重复使用。现在我们对重复感到满意,但这对于创建可重用组件来说是一个很好的做法。
我还想强调,我省略了许多我们可以做的好事,比如使用像 Bootstrap 这样的 CSS 框架等等。我决定专注于以前从未使用过 Vue Router 或构建单页应用程序的人的核心方面。虽然对有些人来说,本教程可能感觉很琐碎,但对初学者来说,它专注于构建传统服务器端应用程序时不同的某些基本概念。