Create a Vue single page application through laravel (6)

Time:2020-2-13

Create a Vue single page application through laravel (6)

The article was forwarded from the professional laravel developer community. Original link: https://learnku.com/laravel/t

We will complete the final part of the basic curd: creating new users. You already have all the tools you need in the topics we discussed earlier, so you can try to create users and compare this article with your work.

If you need to keep up, we stopped deleting users in part 5 and how to redirect users after a successful deletion. We also looked at how to extract the HTTP client into a dedicated module for reuse throughout the application.
Remind me., this tutorial doesn’t focus on permissions; we use the built-in Laraway users show you how to use curd in the context of a Vue router project.

Here is a summary of the series to date:

  • Part 1 – setting up the project and Vue router
  • Part 2 – loading asynchronous data in a Vue router
  • Part 3 – creating a real client in laravel
  • Part 4 – edit users
  • Part 5 – deleting users

Add create user component

First, we will create and configure front-end components to create new users.UsersCreate.vueComponents and theUsersEdit.vueComponents similar to Part 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>

We added forms and input and removed oneonSubmitMethod. The rest of the assembly isUsersEditThe components are the same except thatpasswordInput. A password is required to create a new user. We skipped the password field when editing users, because normally you have a specific password change flow that is different from editing users.

Please note that we can spend some timecreateandeditThe form in the view is extracted into a dedicated component, but we will keep it for a while (or be free to work on it independently). The only difference is to use existing user data (including usersid)Fill in the form instead of creating users with empty forms.

Configuration routing

Next, we need to configure Vue routing and link to the page so that we can navigate to the user created page. openresources/assets/js/app.jsFile and add the following routes (or imports):

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' },
    ],
});

Next, we add the link to theassets/js/views/usersindex.vueNew component in component:

<template>
    <div class="users">
        <!-- ... -->
        <div>
            <router-link :to="{ name: 'users.create' }">Add User</router-link>
        </div>
    </div>
</template>

You should be able to useyarn watchRecompile and see the following:

Create a Vue single page application through laravel (6)

Submit Form

At this point, we haven’t defined a back-end route, so the API will return405 Method Not Allowed。 Let’s refine without defining routesUsersCreateComponentonSubmit()Method, so that we can quickly see the errors generated when submitting the form:

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

For now, our form simply outputs the return value to the console, grabs the error, and switchessaving = falseTo hide the saving state. We try to get it from the return valuemessageProperty or give a default error message.

Next, we areresources/assets/js/api/users.jsAdd to this API modulecreate()Methods:

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

The form will send aPOSTRequest toUsersController。 When you submit the form, you will see the405Error message for error status.

Create a Vue single page application through laravel (6)

Add API interface

We’re going to addAPIInterface to create a new user. This will be similar to editing an existing user. However, this response will return201 CreatedStatus code.

We will first define passAPIPath to store new users:

// routes/api.php
Route::namespace('Api')->group(function () {
    // ...
    Route::post('/users', '[email protected]');
});

Next, openapp/http/controllers/userscontroller.phpFile and addstore()Method:

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']),
    ]));
}

When the user is valid, when the form is submitted, the new user’s response is similar to the following:

{
  "data": {
    "id":51,
    "name":"Paul Redmond",
    "email":"[email protected]"
  }
}

If you submit invalid data, you will receive a similar message as follows:

Create a Vue single page application through laravel (6)

Submit successfully

We’ve dealt with server errors or validation errors; let’s finish by creating a successful user. We will clear the form and redirect to the user’s edit page:

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

Here’s the last oneUsersCreate.vueComponents:

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

End

We now have a simple form with simple data validation to create users. This tutorial takes you through the basic crud in Vue.

As a job, you can define a separate user form component to handle user creation and editing (if you think it’s worth reusing). For now, copying code back and forth is enough, but the best practice is still to create reusable components.

In fact, we can do a lot, including using a CSS framework similar to bootstrap. But in order to let those who have never used Vue router and have never done a single page application get better at it, I decided to focus on the core part. For some people, this tutorial may be trivial, but for novices, it focuses on the main differences between single page applications and traditional server-side applications.