通过 Laravel 创建一个 Vue 单页面应用(六)

我们将完成基本 CURD 的最后一部分:创建新用户。您已经拥有了我们之前讨论过的主题中所需要的所有工具,因此可以尝试创建用户并将本文与您的工作进行比较。

如果您需要跟上,我们在 第5部分  中增加了删除用户的功能,以及在成功删除后如何重定向用户。我们还研究了如何将 HTTP 客户机提取到一个专用模块中,以便在整个应用程序中重用。
提醒一下,本教程并不关注权限;我们使用内置的 Laravel users 表演示如何在 Vue 路由器项目的上下文中使用 CURD。

以下是迄今为止的系列概要:

添加创建用户组件

首先,我们将创建并配置前端组件以创建新用户。UsersCreate.vue 组件与我们在中创建的 UsersEdit.vue 组件类似 第4部分:

<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 输入。创建新用户需要密码。我们在编辑用户时跳过了密码字段,因为通常情况下,您有一个与编辑用户不同的特定密码更改流。

请注意,我们可以花一些时间将 createedit 视图中的表单提取到一个专用组件中,但我们会将其保留一段时间(或者可以自由地独立处理)。唯一的区别是用现有用户数据(包括用户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 来隐藏「saving」状态。我们尝试从返回值中拿到 message 属性或给予一个默认的错误信息。

下一步,我们在  resources/assets/js/api/users.js 这个 API 模块中添加 create() 方法:

export default {
    // ...
    create(data) {
        return client.post('users', data);
    },
    // ...
};

表单将会通过发送一个 POST 请求到 UsersController。这时你提交表单的话会在控制台看到带有 405 错误状态的错误信息。

添加 API 接口

我们准备在 Laravel 中添加 API 接口以创建新用户。这将类似于编辑现有用户。但是,此响应将返回 201 Created 状态代码。

我们将首先定义通过 API 存储新用户的路径:

// routes/api.php
Route::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":"paul@example.com"
  }
}

如果您提交的数据无效,您将收到类似的消息,如下所示:

提交成功

我们已经处理了服务器错误或验证错误的情况;让我们通过创建成功的用户来结束。我们将清除表单并重定向到用户的编辑页:

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 ,也没有做过单页应用的人更好上手,我决定只关注核心部分。对一些人来说,这个教程可能是微不足道的,但对新手来说,它则着重阐述了单页应用和传统的构建服务端应用的主要不同之处。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://laravel-news.com/building-a-vue-...

译文地址:https://learnku.com/laravel/t/34880

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

非常棒的内容 辛苦歪果作者和各位翻译

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!