Nuxt.js Create Tourism Website Chapter 3 Writing of Login Page

Keywords: PHP Vue Mobile axios Attribute

Key knowledge points:

1. Using vuex/store to manage data

2. Logic of login and registration

3.Nuxt Local Storage

 

1. Login page

1.1 Login Page Layout

The code to replace pages/user/login.vue is as follows

<template>
    <div class="container">
        <!-- primary coverage -->
        <el-row 
        type="flex" 
        justify="center" 
        align="middle" 
        class="main">

            <div class="form-wrapper">
                <!-- Form Header tab -->
                <el-row type="flex" justify="center" class="tabs">
                    <span :class="{active: currentTab === index}" 
                    v-for="(item, index) in [`Sign in`, `register`]"
                    :key="index" 
                    @click="handleChangeTab(index)">
                        {{item}}
                    </span>
                </el-row>

                <!-- Login Function Component -->
                <LoginForm v-if="currentTab == 0"/>

                <!-- Registration Function Component -->
                <!-- <RegisterForm v-if="currentTab == 1"/> -->
            </div>
        </el-row>
    </div>
</template>

<script>
import LoginForm from '@/components/user/loginForm'
export default {
    components: {
      LoginForm
    },
    data(){
        return {
            currentTab: 0
        }
    },
    methods: {
        handleChangeTab(index){
            this.currentTab = index;
        },
    }
}
</script>

<style scoped lang="less">
.container{
    background:url(http://157.122.54.189:9095/assets/images/th03.jfif) center 0;
    height: 700px;
    min-width:1000px;

    .main{
        width:1000px;
        height: 100%;
        margin:0 auto;
        position: relative;
        
        .form-wrapper{
            width:400px;
            margin:0 auto;
            background:#fff;
            box-shadow: 2px 2px 0 rgba(0,0,0,0.1);
            overflow:hidden;
            
            .tabs{
                span{
                    display: block;
                    width:50%;
                    height: 50px;
                    box-sizing: border-box;
                    border-top:2px #eee solid;
                    background:#eee;
                    line-height: 48px;
                    text-align: center;
                    cursor: pointer;
                    color:#666;

                    &.active{
                        color:orange;
                        border-top-color: orange;
                        background:#fff;
                        font-weight: bold;
                    }
                }
            }
        }
    }
}
</style>
pages/user/login.vue

 

1.2 Login Function

 

Ideas:

1. Create a new loginForm.vue form component in components/user

2. Form components using Element-ui

3. Form data binding

4. Form validation

5. Login Interface

 

Implementation steps:

1. Create a new loginForm.vue form

Create a new loginForm.vue component in components/user, as follows

<template>
    <el-form 
        :model="form" 
        ref="form"
        :rules="rules" 
        class="form">

        <el-form-item class="form-item">
            <el-input 
            placeholder="User name/Mobile phone">
            </el-input>
        </el-form-item>

        <el-form-item class="form-item">
            <el-input 
            placeholder="Password" 
            type="password">
            </el-input>
        </el-form-item>

        <p class="form-text">
            <nuxt-link to="#">Forget password </nuxt-link>"
        </p>

        <el-button 
        class="submit"
        type="primary"
        @click="handleLoginSubmit">
            //Sign in
        </el-button>
    </el-form>

</template>

<script>
export default {
    data(){
        return {
            // Form Data
            form: {},
            // Form rules
            rules: {},
        }
    },
    methods: {
        // Submit login
        handleLoginSubmit(){
           console.log(this.form)
        }
    }
}
</script>

<style scoped lang="less">
    .form{
        padding:25px;
    }

    .form-item{
        margin-bottom:20px;
    }

    .form-text{
        font-size:12px;
        color:#409EFF;
        text-align: right;
        line-height: 1;
    }

    .submit{
        width:100%;
        margin-top:10px;
    }
</style>
components/user/loginForm.vue

Note: After adding components, you can import them in pages/user/login.vue, import location, and remove the annotations of the components in the following section

<!-- Login Function Component -->
<!-- <LoginForm v-if="currentTab == 0"/> -->

 

2. Form data binding

Modify data form data, and then bind to the corresponding form field using v-model.

Edit components/user/loginForm.vue

// Other code...

data(){
    return {
        // Form Data
        form: {
            username: "",   // Username/Mobile phone
            password: ""    // Login password
        },
        // Other code...
    }
},
    
// Other code...

 

Binding to the corresponding form field using v-model

<!-- Other code... -->

<el-form-item class="form-item">
    <!-- Added v-model -->
    <el-input 
              placeholder="User name/Mobile phone"
              v-model="form.username">
    </el-input>
</el-form-item>

<el-form-item class="form-item">
    <!-- Added v-model -->
    <el-input 
              placeholder="Password" 
              type="password"
              v-model="form.password">
    </el-input>
</el-form-item>

<!-- Other code... -->

 

3. Form validation

After two-way data is bound to the form field, we can now submit the form, but before submitting, we need to verify that the following form field is legal, such as not empty.

Continue editing components/user/loginForm.vue

// Other code...

data(){
    return {
        // Other code...

        // Form rules
        rules: {
            username: [
                { 
                    required: true, 
                    message: 'enter one user name', 
                    trigger: 'blur' 
                },
            ],
            password: [
                { 
                    required: true, 
                    message: 'Please input a password', 
                    trigger: 'blur' 
                },
            ],
        },
    }
},
    
// Other code...

 

Add prop attribute to el-form-item

<!-- Other code... -->

<!-- Added prop attribute -->
<el-form-item class="form-item" prop="username">
    <el-input 
              placeholder="User name/Mobile phone"
              v-model="form.username">
    </el-input>
</el-form-item>

<!-- Added prop attribute -->
<el-form-item class="form-item" prop="password">
    <el-input 
              placeholder="Password" 
              type="password"
              v-model="form.password">
    </el-input>
</el-form-item>

<!-- Other code... -->

Now you can try to empty the value of the input input box, and the prompt content defined in rules will appear.

 

4. Login Interface

Next, we need to call the login interface to log in. If everything is normal, we can see the user information returned from the background. If the login fails, we need to deal with the wrong return in a unified way, which we will achieve in the end.

Modify submission login events for components/user/loginForm.vue:

// Other code...

// Submit login
methods: {
    handleLoginSubmit(){
        // validate form
        this.$refs['form'].validate((valid) => {
            // by true Represents no errors
            if (valid) {
                this.$axios({
                    url: "/accounts/login",
                    method: "POST",
                    data: this.form
                }).then(res => {
                    console.log(res.data);
                })
            }
        })
    }
}

// Other code...

 

Now that the login interface can be accessed, the server provides us with a test account password.

Account number: 13800138000

Password: 123456

 

If the normal login should be able to see the printed user information in the control, then the login is successful.

 

5. Summary

  1. Create a new loginForm.vue form component in components/user

  2. Binding data and validating forms with form components of Element-ui

  3. Call login interface

 

2. Use store to manage data

Ideas:

User login registration behavior and user information are managed by vuex.

1. Create new user.js under the store folder

2. Implement login in store/user.js and save data to store state

3. Display user information in header build

 

Implementation steps:

New status file

// Every small warehouse must expose state, mutations

export const state = {
userInfo: {
// token for user authentication
token: "",
// User Information
user: {

}

}
}

export const mutations = {
// Setting User Information
setUserInfo(state, data){
state.userInfo = data;
}
}

 

After the login request is sent successfully, the data input by the user is stored in the store warehouse of vuex.

        // Submit login
        handleLoginSubmit(){
          // validate form
          this.$refs['form'].validate((valid)=>{
            // by true Represents no errors
            if(valid){
              this.$axios({
                url: '/accounts/login',
                method: 'POST',
                data: this.form
              }).then(res=>{
                // 1.Save to vuex, Note the addition of namespaces when calling methods,That's the module where the method is located. user
                this.$store.commit('user/setUserInfo', res.data)
              })
            }
          })
        }
loginForm.vue

 

Display the user's login phone number in the page and replace the following code in the header.vue component.

<span class="el-dropdown-link">
              <img src="http://157.122.54.189:9095/assets/images/avatar.jpg" alt="">
              {{this.$store.state.user.userInfo.user.username}}
              <i class="el-icon-arrow-down el-icon--right"></i>
</span>

 

The use of store under nuxt

1. First, create a new module of data, a module is a file, the name of the file is the name of the module, such as a new user module, each module can expose three commonly used attributes.

// Every small warehouse must be exposed. state, mutations

export const state = {
  userInfo: {
    // User-authenticated token
    token: "",
    // User Information
    user: {

    }
    
  }
}

export const mutations = {
  // Setting User Information
  setUserInfo(state, data){
    state.userInfo = data;
  }
}
store/user.js

 

2. Read the user below user

{{ $store.state.user.userInfo.user.username }} 
components/header.vue

 

3. The method under mutations must be called with the module name

// 1.Save to vuex
this.$store.commit("user/setUserInfo", res.data);
components/user/loginForm.vue

 

Store store data locally

Because this project is a Node.js project, you can't use the localStorage method to store it. Here you need to install a plug-in to solve this local storage problem.

Plug-in Address: https://github.com/robinvdvleuten/vuex-persistedstate

Installation dependency

Installation: yarn add vuex-persisted state

 

Configure nuxt.config.js and add the following configuration in plugins.

{ src: '~/plugins/localStorage.js', ssr: false }

 

Create a new localStorage.js in the plugins directory and add the following code.

// ~/plugins/localStorage.js

import createPersistedState from 'vuex-persistedstate'

export default ({store}) => {
  window.onNuxtReady(() => {
    createPersistedState({
        key: 'store'
    })(store)
  })
}

Using a third-party plug-in vuex-persisted state, store data is automatically saved to the local store through this plug-in, and local data is automatically reassigned to the store after the application is loaded.

 

3. Judging Display Page Information

When the locally saved data is cleared, the page will still display the avatar. The "Log in/Register" button should be displayed, and the following code can be modified.

<div>
        <div v-if="!$store.state.user.userInfo.token">
          <nuxt-link to="/user/login">Sign in / register</nuxt-link>
        </div>
        <div v-else>
          <el-dropdown>
            <span class="el-dropdown-link">
              <img
                :src="$axios.defaults.baseURL + $store.state.user.userInfo.user.defaultAvatar"
                alt
              />
              {{this.$store.state.user.userInfo.user.username}}
              <i
                class="el-icon-arrow-down el-icon--right"
              ></i>
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>Personal Center</el-dropdown-item>
              <el-dropdown-item>Sign out</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
      </div>
header.vue

 

4. Log out

Add an exit event to the exit button in the header.vue component

<! - Binding native events to elementUI components via native - >
<el-dropdown-item@click.native="handleLogout">exit </el-dropdown-item>

 

  methods: {
    // Log out and empty local user data
    handleLogout(){
      this.$store.commit('user/clearUserInfo');
    }
  }

 

Add a method to empty data in mutations of store/user.js module.

  // Set user data to null
  clearUserInfo(state){
    state.userInfo = {};
  }

After successful login, jump to the home page and add the following code in loginForm.vue.

// Jump to Home Page
this.$router.push("/");

 

5. Use of actions

actions are asynchronous modified warehouse data and rely on mutations.

mutations: Used to synchronously modify warehouse data.

actions: Used to modify warehouse data asynchronously, such as login.

 

Write the code to send the login request into the actions method for easy maintenance and invocation.

Add actions in store/user.js.

// Asynchronous Modification of Warehouse Data
export const actions = {
  // login(store, data){
  login({commit}, data){
    return this.$axios({
      url: "/accounts/login",
      method: "POST",
      data:data
    }).then(res => {
      // store.commit("setUserInfo", res.data)
      commit("setUserInfo", res.data)
      // 1.Save to vuex, Note the addition of namespaces when calling methods,That's the module where the method is located. user

      // The behavior after login should be executed by the calling page, which cannot be written to death, because the successful login operation of each page may be different.
      // this.$router.push("/");
      
    });
  }
}

 

In the loginForm.vue component, the code for the method of sending login requests is changed to:

  methods: {
    // Submit login
    handleLoginSubmit() {
      // validate form
      this.$refs["form"].validate(valid => {
        // by true Represents no errors
        if (valid) {
          this.$store.dispatch('user/login', this.form).then(res=>{
            this.$router.push('/');
          })
        }
      });
    }
  }

 

Action Summary

Under what circumstances can methods be encapsulated into actions?

When asynchronous methods need to be reused, consider encapsulating methods into actions, such as login.

 

How should actions be declared?

The first parameter of the method in actions is the store object, under which all store attributes (commit, dispatch, state...) can be accessed to modify state data with commit.

The second is optional, which is the parameter passed in.

 

How do I call the actions method?

this.$store.dispatch('user/login', this.form).then(res=>{ this.$router.push('/'); })

 

store summary

When will Vuex be used?

There is a lot of project data, and when multiple components are needed to share data, vuex can be used.

 

How do you use it?

state: Storing data

mutations: Setting up data to modify state

Action: Modify state data asynchronously and put reusable requests into actions (actions need to call mutations to modify data)

 

Problems to be noticed when using

Don't Write Wrong Words

Note that methods calling mutations and actions remember to add module names (namespaces)

Posted by tempa on Mon, 15 Jul 2019 15:48:20 -0700