小白学 VUE 系列vue cli 制作登录注册页面

附件下载

源码示例.zip

附件大小:170 KB

免费

立即下载

vue cli 登录注册实例步骤

本文采用 vue cli 4 版本,vue2.6版本

  • 1.安装脚手架(忽略)
  • 2.创建项目
  • 3.安装依赖包
  • 4.部署 vuex 数据
  • 5.编写接口数据,本地采用 mock.js 模拟数据
  • 6.封装 axios 请求
  • 7.编写接口请求方法
  • 8.编写 vuex 异步接口逻辑
  • 9.辅助方法
  • 10.制作页面编写逻辑实现整个流程

2.vue cli 登录注册创建项目

vue create login

黑白课堂
空格键 进行选择,然后 回车 下一步
黑白课堂
黑白课堂
选择2.x,路由本地选择history
黑白课堂
黑白课堂
黑白课堂
黑白课堂
黑白课堂

Vue CLI v4.5.12
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex, CSS Pre-processors
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Where do you prefer placing config for Babel, ESLint, etc.? In package.json
? Save this as a preset for future projects? Yes
? Save preset as: vue2.xNoCodeCheck

静候等待安装完毕。
黑白课堂
提示这样就表示安装完毕了。

3. 安装依赖包

这里需要用到axios,mock,所以进行执行如下代码

npm install axios
npm install --save-dev mockjs

axios使用教程参考
Mock使用教程参考

--save-dev 表示开发时候用到的依赖,正式环境不需要加载依赖包。

4.部署 vuex 数据

我们登录注册功能,主要分了以下几个常用的状态:

  • 1.登录状态isLogin
  • 2.登录接口token
  • 3.会员昵称nickname
  • 4.会员iduserId
  • 5.会员对象信息:userInfo

除了登录状态外,我们还需要请求后端数据,所以需要使用到 mutations,actions 方法。我们先分析异步接口:

  • 1.注册动作register
  • 2.登录动作login
  • 3.退出登录loginOut
  • 4.检验登录状态checkLogin

分析出来了异步接口,那么异步接口需要交互状态属性更改,所以需要用到 vuex mutations:

  • 1.注册登录后状态属性更改updateLoginRegister
  • 2.退出登录属性更改loginOutUpdate

这里我们把上述所需的功能进行编写,这里采用 vuex 的命名空间模块模式。所以新建/src/store/modules/user.js

export default {
    namespaced:true,
    state:{
        isLogin:"",
        token:"",
        nickname:"",
        userId:"",
        userInfo:""
    },
    mutations:{
        updateLoginRegister(state,data){

        },
        loginOutUpdate(state){

        }
    },
    actions:{
        register(content,data){

        },
        login(content,data){

        },
        loginOut(content,data){

        },
        checkLogin(content,data){

        }
    }
}

将其引入到 \src\store\index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

import user from './modules/user';

export default new Vuex.Store({
  modules: {
      user
  }
})

5.编写接口数据,本地采用 mock.js 模拟数据

我们在 src 下新建一个 api 文件夹,再新建一个 mockApi.jsconfig.js 文件,编写 vuex 里面的4个 actions 接口请求。
config.js,这个主要用来配置接口配置信息。例如:

export const BASE_URL="http://api.kq.com/api/v1";

mockApi.js 主要是拦截接口地址,进行本地测试。

const Mock = require('mockjs');
import {BASE_URL} from './config';

//登录
var login = function (options) {
    let params = JSON.parse(options.body);
    if (!params.account) {
        return {
            code: 1,
            msg: "账号不能为空"
        }
    }
    if (!params.password) {
        return {
            code: 1,
            msg: "密码不能为空"
        }
    }
    let users = localStorage.getItem("users");
    if (!users) {
        return {
            code: 1,
            msg: "请先注册"
        }
    }
    let data = null;
    users = JSON.parse(users);
    for (let item in users) {
        if (users[item].account == params.account && users[item].password == params.password) {
            data = users[item];
            break;
        }
    }
    if (data) {
        return {
            code: 200,
            msg: "登录成功",
            data: data
        }
    }
    return {
        code: 1,
        msg: "登录失败"
    }

};

//注册
var register = function (options) {
    let params = JSON.parse(options.body);

    if (!params.account) {
        return {
            code: 1,
            msg: "账号不能为空"
        }
    }
    if (!params.name) {
        return {
            code: 1,
            msg: "昵称不能为空"
        }
    }
    if (!params.password) {
        return {
            code: 1,
            msg: "密码不能为空"
        }
    }

    let users = localStorage.getItem("users");
    if (!users) {
        users = {};
    } else {
        users = JSON.parse(users);
    }

    if (users[params.account]) {
        return {
            code: 1,
            msg: "已经被注册了"
        }
    }
    let data = {
        name: params.name,
        account: params.account,
        id: Object.keys(users).length + 1,
        token: (new Date()).getTime(),
        password: params.password
    }
    users[params.account] = data;
    localStorage.setItem('users', JSON.stringify(users));
    data.password = "";
    return {
        code: 200,
        msg: "注册成功",
        data: data
    }
}

//账号信息
var userInfo = function (options) {
    let params = JSON.parse(options.body);
    let users = localStorage.getItem("users");
    if (!users) {
        return {
            code: 1,
            msg: "还没有登录"
        }
    }
    users = JSON.parse(users);
    let data = null;
    for (let item in users) {
        if (users[item].token == params.api_token) {
            data = users[item];
            break;
        }
    }

    if (data) {
        return {
            code: 200,
            msg: "登录成功",
            data: data
        }
    }
    return {
        code: 1,
        msg: "还没有登录"
    }

}
//注册拦截
Mock.mock(BASE_URL + '/register', 'post', register);
//登录拦截
Mock.mock(BASE_URL + '/login', 'post', login);
//检验和获取用户信息拦截
Mock.mock(BASE_URL + '/user', 'post', userInfo);

login/src/main.js 引入

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false;
import './api/mockApi.js'  //引入mock

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

6.封装 axios 请求

新建login/src/assets/js/request.js

import Axios from 'axios';
import {BASE_URL} from '../../api/config';

export function post(url, data, _config) {
    let config = {
        method: "post",
        url: url,
        data: data
    };
    //合并参数
    Object.assign(config, _config);
    return request(config);
}

export function get(url, data, _config) {
    let config = {
        method: "get",
        url: url,
        data: data
    };
    //合并参数
    Object.assign(config, _config);
    return request(config);
}

export function request(_config) {

    var req = Axios.create({
        baseURL: BASE_URL
    });
    req.interceptors.request.use(function (config) {
        // 在发送请求之前做些什么Authorization
        //判断是否登录,登录就注入token
        let token = localStorage.getItem("token");
        if (token) {
            if (!config.data) {
                let data = {
                    "api_token": token
                }
                config.data = JSON.stringify(data);
            } else {

                config.data.api_token = token;

            }

        }

        return config;
    }, function (error) {
        // 对请求错误做些什么
        return Promise.reject(error);
    });
    req.interceptors.response.use(function (response) {
        // 对响应数据做点什么
        return response;
    }, function (error) {
        // 对响应错误做点什么
        return Promise.reject(error);
    });
    return req.request(_config)

}

export default {
    post,
    get,
    request
}

src/main.js 引入到全局

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './api/mockApi.js'  //引入mock
import request from  './assets/js/request.js'

Vue.config.productionTip = false;

Vue.prototype.$request=request;

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

7.编写接口请求方法

新建/src/api/user/index.js

import request from '../../assets/js/request'
//登录
export function login(account,password) {
    return request.post('login',{
        type:"h5",
        account,password
    })
}
//注册
export function register(name,account,password) {
    return request.post('register',{
        type:"h5",
        name, account,password
    })
}

//个人信息
export function info() {
    return request.post("user")
}

//个人信息
export function loginOut() {
    return request.post("loginOut")
}

8.编写 vuex 异步接口逻辑

import {info, login, register, loginOut} from "../../api/user/index";

export default {
    namespaced: true,
    state: {
        isLogin: localStorage.getItem("isLogin") || false,
        token: localStorage.getItem("token") || "",
        nickname: localStorage.getItem("nickname") || "",
        userId: localStorage.getItem("userId") || "",
        userInfo: localStorage.getItem("userId") ? JSON.parse(localStorage.getItem("userId")) : {}
    },
    mutations: {
        updateLoginRegister(state, data) {
            state.isLogin = true;
            state.token = data.token;
            state.nickname = data.name;
            state.userId = data.id;
            localStorage.setItem("isLogin", true);
            localStorage.setItem("token", data.token);
            localStorage.setItem("nickname", data.name);
            localStorage.setItem("userId", data.id);
            localStorage.setItem("userInfo", JSON.stringify(data));
        },
        loginOutUpdate(state) {
            state.isLogin = false;
            state.token = "";
            state.nickname = "";
            state.userId = "";
            state.userInfo = "";
            localStorage.removeItem("isLogin");
            localStorage.removeItem("token", "");
            localStorage.removeItem("nickname");
            localStorage.removeItem("userId");
            localStorage.removeItem("userInfo")
        }
    },
    actions: {
        register(content, data) {
            console.log(data);
            return register(data.username, data.account, data.password).then(res => {
                //进行
                if (res.data.code == 200) {
                    if (data.complete) {
                        //进行 commit
                        content.commit("updateLoginRegister", res.data.data)
                        return data.complete(res.data.data);
                    }

                } else {
                    if (data.fail) {
                        return data.fail(res.data);
                    } else {
                        console.log('我出发了');
                        return alert(res.data.msg)
                    }

                }
            });
        },
        login(content, data) {
            return login(data.account, data.password).then(res => {
                if (res.data.code == 200) {
                    if (data.complete) {
                        //进行 commit
                        content.commit("updateLoginRegister", res.data.data)
                        return data.complete(res.data.data);
                    }

                } else {
                    if (data.fail) {
                        return data.fail(res.data);
                    } else {
                        return alert(res.data.msg)
                    }

                }
            });
        },
        loginOut(content, data) {
            return loginOut().then(res => {
                if (res.data.code == 200) {
                    if (data.complete) {
                        content.commit("loginOutUpdate")
                        return data.complete(res.data);
                    }

                } else {
                    if (data.fail) {
                        return data.fail(res.data);
                    } else {
                        return alert(res.data.msg)
                    }

                }
            });

        },
        checkLogin(content, data) {
            return info().then(res => {
                if (res.data.code != 200) {
                    if (data.complete) {
                        return data.complete();
                    }
                }
            })
        }
    }
}

9.辅助方法

比如检验登录,这个写到辅助函数里面,方便我们快速调用。新建/src/assets/js/function.js

export function checkLogin(_this){
    _this.$store.dispatch('user/checkLogin',{
        complete:()=>{
            _this.$store.commit("user/loginOut");
            _this.$router.replace("/login")
        }
    });
}

10.制作页面编写逻辑实现整个流程

创建页面:

  • 1.登录页面
  • 2.注册页面
  • 3.会员中心

Login.vue

<template>
  <div class="about">
   <h1>登录</h1>
    <input type="text" v-model="username" placeholder="请输入账号"><br/>
    <input type="text" v-model="password" placeholder="请输入密码"><br/>
    <button type="button" @click="submit">登录</button>
  </div>
</template>
<script>
    import {mapActions} from 'vuex';
  export  default {
      name: 'Login',
      data(){
          return {
              username:"",
              password:""
          }
      },
      methods:{
          ...mapActions({
             login:'user/login'
          }),
         async submit(){
              if(!this.username){
                  alert('请输入账号');
                  return false;
              }
              if(!this.password){
                  alert('请输入密码');
                  return false;
              }
             this.login({ account:this.username,password:this.password,complete:res=>{
                    this.$router.replace("/user")
                 }});

          }
      }
  }
</script>
<style scoped lang="less">
    input{
        line-height: 30px;
        margin-bottom: 10px;
        outline: none;
    }
</style>

Register.vue

<template>
  <div class="about">
   <h1>注册</h1>
      <input type="text" v-model="username" placeholder="请输入昵称"><br/>
    <input type="text" v-model="account" placeholder="请输入账号"><br/>
    <input type="text" v-model="password" placeholder="请输入密码"><br/>
    <button type="button" @click="submit">注册</button>
  </div>
</template>
<script>
    import {mapActions} from 'vuex';

    export  default {
      name: 'Register',
      data(){
          return {
              username:"",
              account:"",
              password:""
          }
      },
      methods:{
          ...mapActions({
              register:"user/register"
          }),
          submit(){
              if(!this.username){
                  alert('请输入昵称');
                  return false;
              }
              if(!this.account){
                  alert('请输入账号');
                  return false;
              }
              if(!this.password){
                  alert('请输入密码');
                  return false;
              }
              this.register({
                  username:this.username,account:this.account,password:this.password,complete:res=>{
                      this.$router.replace("/user");
                  }
              });

          }
      }
  }
</script>
<style scoped lang="less">
    input{
        line-height: 30px;
        margin-bottom: 10px;
        outline: none;
    }
</style>

User.vue

<template>
    <div class="home">
        个人主页
        <br/>
        昵称:{{ this.$store.state.user.nickname}}
        <br/>
        ID:{{ this.$store.state.user.userId }}
    </div>
</template>

<script>
    import {checkLogin} from "../assets/js/function";

    export default {
        name: 'User',
        data() {
            return {
                username: "",
                userId: ""
            }
        },
        created(){
            checkLogin(this);

        },
        methods: {}
    }
</script>

login/src/App.vue

<template>
    <div id="app">
        <div id="nav">
            <router-link to="/">首页</router-link>
            |
            <template v-if="$store.state.user.isLogin==false">
                <router-link to="/register">注册</router-link>
                |
                <router-link to="/login">登录</router-link>

            </template>
            <template v-else>
                <router-link to="/user">个人中心</router-link>
                |
                <a href="javascript:void(0)" @click="loginOut" class="">退出登录</a>

            </template>
        </div>
        <router-view/>
    </div>
</template>

<script>
    import {mapActions} from 'vuex';
    export default {
        name: 'home',
        data() {
            return {}
        },
        created(){
            console.log
        },
        methods: {
            ...mapActions({
                loginOut2: "user/loginOut"
            }),
            loginOut() {
                this.loginOut2({
                    complete: () => {
                        this.$router.replace("/login");
                    }
                })

            }
        }
    }
</script>
<style lang="less">
    #app {
        font-family: Avenir, Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
    }

    #nav {
        padding: 30px;

        a {
            font-weight: bold;
            color: #2c3e50;

            &.router-link-exact-active {
                color: #42b983;
            }
        }
    }
</style>

User.vue

<template>
    <div class="home">
        个人主页
        <br/>
        昵称:{{ this.$store.state.user.nickname}}
        <br/>
        ID:{{ this.$store.state.user.userId }}
    </div>
</template>

<script>
    import {checkLogin} from "../assets/js/function";

    export default {
        name: 'User',
        data() {
            return {
                username: "",
                userId: ""
            }
        },
        created(){
            checkLogin(this);

        },
        methods: {}
    }
</script>

整个演示

黑白课堂

评论区 (0)

没有记录
支持 markdown,图片截图粘贴拖拽都可以自动上传。
黑白课堂

黑白课堂 · 技术专家

专业PHP开发

年度VIP 站长创业者玉树凌风每天醒来0收入
查看更多

最新视频课程

钻级赞助商