[聚合文章] vue vue-router vuex element-ui axios 的学习笔记(七)完善登录注册

vue.js 2017-11-20 1 阅读

现在我们已经能够在服务器环境下完成注册操作了

登录功能

login.vue

<template>
  <el-main>
    <el-form 
      :model="LoginForm" 
      ref="LoginForm" 
      :rules="rule"
      label-width="0"
      class="login-form">
      <h3>用户登录系统</h3>

      <el-form-item prop="username">
        <el-input 
          type="text" 
          v-model="LoginForm.username" 
          placeholder="username" >
        </el-input>
      </el-form-item>

      <el-form-item prop="password">
        <el-input 
          type="password" 
          v-model="LoginForm.password" 
          placeholder="password" >
        </el-input>
      </el-form-item>

      <el-form-item >
        <el-button 
          type="danger" 
          class="submitBtn"
          round
          @click.native.prevent="submit"
          :loading="logining">
          登录
        </el-button>
        <el-button 
          type="primary"
          class="resetBtn" 
          round
          @click.native.prevent="reset">
          重置
        </el-button>
        <hr>
        <p>还没有账号,马上去<span class="to" @click="toregin">注册</span></p>
      </el-form-item>
    </el-form>
  </el-main>
</template>

<script>
import {LoginUser} from '../api/api'
export default {
  // ....
  data () {
    return {
      LoginForm: {
        username: '',
        password: ''
      },
      logining: false,
      rule: {
        username: [
          {
            required: true,
            max: 14,
            min: 7,
            message: '用户名是必须的,长度为7-14位',
            trigger: 'blur'
          }
        ],
        password: [
          {
            required: true,
            message: '密码是必须的!',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  methods: {
    // ...
    submit () {
      this.$refs.LoginForm.validate(valid => {
        if (valid) {
          this.logining = true
          // console.log('开始请求后台数据,验证返回之类的操作!')
          // 登录作为参数的用户信息
          let LoginParams = {
            username: this.LoginForm.username,
            password: this.LoginForm.password
          }
          // 调用axios登录接口
          LoginUser(LoginParams).then(res => {
            this.logining = false
            // 根据返回的code判断是否成功
            let {code, msg, user} = res.data
            if (code !== 200) {
              this.$message({
                type: 'error',
                message: msg
              })
            } else {
              this.$message({
                type: 'success',
                message: msg
              })
              // 将返回的数据注入sessionStorage
              sessionStorage.setItem('user', JSON.stringify(user))
              // 跳转到我的信息的页面
              this.$router.push('/manger/my')
            }
          })
        } else {
          console.log('submit err')
        }
      })
    },
    reset () {
      this.$refs.LoginForm.resetFields()
    },
    toregin () {
      this.$router.push('/regin')
    }
  }
}
</script>

<style scoped>
.login-form {
  margin: 20px auto;
  width: 310px;
  background: #fff;
  box-shadow: 0 0 35px #B4BCCC;
  padding: 30px 30px 0 30px;
  border-radius: 25px; 
}
.submitBtn {
  width: 65%;
}
.to {
  color: #67C23A;
  cursor: pointer;
}
</style>

登录页面和注册页面差不多的,但测试的话又得打一包,很麻烦,所以暂时可以用axios-mock-adapter 来模拟测试一下,等功能都完善之后再打包丢到服务器测试

1、安装axio-mock-adapter

2、写个假数据

  • 1、在data.js 里面添加2个用户

data.js

import avatarLee from '../assets/avatar.jpg'
import avatarZhang from '../assets/avatar2.jpg'
const users = [
  {
    username: 'lytton',
    password: '123456',
    email: '123@163.com',
    tel: '15181589155',
    name: '李小白',
    time: '2017-11-11',
    avatar: avatarLee
  },
  {
    username: 'zhangsan',
    password: '123456',
    email: '321@163.com',
    tel: '13789546327',
    name: '张三',
    time: '2017-08-17',
    avatar: avatarZhang
  }
]
export default {users}

3、写mock-adapter 接口

在data文件夹下写一个index.js

mock.js

import axios from 'axios'
import Adapter from 'axios-mock-adapter'
import {users} from './data'
import avatarDefault from '../assets/logo.png'
export default {
  init () {
    // 创建Adapter 实例
    const mock = new Adapter(axios)

    // 模拟登录接口
    mock.onPost('/login').reply(config => {
      // 解析axios传过来的数据
      let {username, password} = JSON.parse(config.data)
      return new Promise((resolve, reject) => {
        // 先创建一个用户为空对象
        let user = {}
        // 判断模拟的假数据中是否有和传过来的数据匹配的
        let hasUser = users.some(person => {
          // 如果存在这样的数据
          if (person.username === username && person.password === password) {
            let user = JSON.parse(JSON.stringify(person))
            user.password = ''
            return true
          } else {
            // 如果没有这个person
            return false
          }
        })
        // 如果有这么一个人
        if (hasUser) {
          resolve([200, { code: 200, msg: '登录成功', user }])
          // 如果没有这个人
        } else {
          resolve([200, { code: 500, msg: '账号或密码错误' }])
        }
      })
    })

    // 模拟注册接口
    mock.onPost('/regin').reply(config => {
      let {username, password, email, tel, name} = config.params
      users.push({
        username: username,
        password: password,
        email: email,
        name: name,
        tel: tel,
        avatar: avatarDefault
      })
      return new Promise((resolve, reject) => {
        resolve(config.data)
      })
    })
  }
}

4、配置一下adapter

main.js

5、测试

cnpm run dev

这好尴尬,我添加的假数据用户名没7位,其实用户名没必要这么长啊,改成3位好了

还有问题,来了三个警告,有没有大神指教一下

不过应该不影响逻辑的,继续测试



跳转顺利,但数据了????找找问题


找到原因了

测试了几次,找到问题了,
mock.js写出问题了
这是原来的代码

首先定义了let user = {},
在下面的if()里面,我又 let user = ‘我们要返回的数据’
然后在if ()以及hasUser()的外面我resolve user回去的时候,因为作用域的问题,自然就是把这个空的user 返回回去了
正确的写法就是把if()里面let user = xxxxx,的let去掉

因为测试了几次,所以可以看见在console 里面居然看见了2个user的信息,这个user可是写进sessionStorage的啊,按道理sessionStorage里面只该有一个user的信息,这个太危险了,不过我们还是把header上的按钮先变成用户信息吧

打开header.vue
首先添加这些代码:

然后把其它功能完善一下

测试一下

看起来效果还是不错的

但点击我的工作太,退出登录居然没效果,然后我改为这样

就有效果了

这是为什么???有时候用@click.native没有效果,要用@click,有时候正好相反@click没效果,要用@click.native,有没有大佬来解惑一番?


然后我又发现一个问题了,是这样的,我先退出登录

然后登录

很明显sessionStorage里面用户数据是存在的,但右上角还是登录按钮,并没有变为用户信息?

我本来以为是mounted 写错了,但发现并不是,因为我刷新一下就这样了

变正常了?并不是,我仔细思考了一下,mounted是在页面创建的时候执行,我刷新一下,右边是先有了上面的user数据,才出现下面的warning和console,所以事实是这样的


我登录之后,user数据写入sessionStorage,然后跳转到manger/my页面,而中间那个main部分的页面是才创建的,会显示name,而header.vue这个页面是我打开浏览器,输入这个地址的时候创建的,不管我登录、注册还是登出,切换到那个页面,header.vue并没有被销毁后重建,自然不会执行mounted()这个行为。只有我刷新页面它才会执行。

当然既然知道问题出在哪里,那自然就能找出解决的办法

  • 1:换一个写法,app.vue里面不要写header,footer

把header,footer,写在home里面,这样跳转的时候就可以整个页面重建了,但这样的话要修改很多地方,路由要重写,很麻烦。

  • 2、用$emit 和$on的方法,就是组件之间通讯,但我看到一个专门干这事的vuex之后,本着多学习的思想,决定用vuex来解决,虽然看起来用vuex更麻烦一些。

突然看见上面的图片写着<el-footer class="el-footer.">,这个.让我很是羞愧啊,辣眼睛,赶紧去改掉。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。