(四)Vue项目——微商城:实现登录和注册

目录

登录和注册

1.我的信息

2.登录页面

3.实现登录功能

4.登录接口和浏览器允许跨域

5.记住登录状态

6.用户菜单

7.退出登录

7.注册页面

8.注册接口

9.实现注册功能


登录和注册

1.我的信息

编写pages\User.vue文件

<template>

  <div class="member">

    <div class="header-con">

      <router-link :to="{ name: 'login' }" class="mui-navigate-right">

        <div class="user-info">

            <!-- 用户信息 -->

        </div>

      </router-link>

    </div>

  </div>

</template>

在“<!-- 用户信息 -->”后面编写如下代码,图片资源需要手动导入assets/images目录

<div class="avatar-con">

  <div class="avatar">

    <img src="../assets/images/avatar_default.png" class="image-info">

  </div>

</div>

<div class="person-con">

  <span>登录 / 注册</span>

</div>

样式:

<style lang="scss" scoped>

.member {

  margin-bottom: 15px;

  .header-con {

    padding: 10px;

    background-color: #fff;

    .user-info {

      position: relative;

      overflow: hidden;

      width: 100%;

      height: 120px;

      background: linear-gradient(90deg, #28a2ff, #ffd787);

      box-shadow: 0 0.1rem 0.25rem #f8e3c6;

      .avatar-con {

        position: absolute;

        left: 15px;

        top: 50%;

        transform: translateY(-50%);

        .avatar {

          width: 60px;

          height: 60px;

          overflow: hidden;

          box-shadow: 0 2px 10px rgba(0, 0, 0, 15);

          border: 1px solid hsla(0, 0%, 100%, 0.4);

          border-radius: 50% 50%;

          .image-info {

            width: 100%;

            height: 100%;

          }

        }

      }

      .person-con {

        position: absolute;

        left: 90px;

        top: 50%;

        transform: translateY(-50%);

        color: #fff;

      }

    }

  }

}

</style>

48eb794b1e6f442daff68540bf7d701d.png

2.登录页面

src\router.js

import Login from './pages/user/Login.vue'

routes数组中添加

{ path: '/user/login', component: Login, name: 'login', meta: { title: '登录' } },

创建src\pages\user\Login.vue

<template>

  <div class="login">

    <div class="mui-content">

      <form class="mui-input-group">

        <div class="mui-input-row">

          <label>账号</label>

          <input v-model="loginForm.username" type="text" class="mui-input-clear mui-input" placeholder="请输入账号" />

        </div>

        <div class="mui-input-row">

          <label>密码</label>

          <input v-model="loginForm.password" type="password" class="mui-input-clear mui-input" placeholder="请输入密码" />

        </div>

      </form>

      <div class="mui-content-padded">

        <button @click="login" type="button" class="mui-btn mui-btn-block mui-btn-primary">登录</button>

        <div class="link-area">

          <a @click="register">还没有账号?前往注册</a>

        </div>

      </div>

    </div>

  </div>

</template>

逻辑:

<script>

export default {

  data () {

    return {

      loginForm: {

        username: '',

        password: ''

      }

    }

  },

  methods: {

    login () {

     //登录

    },

    register () {

      this.$router.push({ name: 'register' })

    }

  }

}

</script>

样式:

<style lang="scss" scoped>

.mui-input-group {

  margin-top: 10px;

  background-color: transparent;

}

.mui-input-group label {

  width: 22%;

}

.mui-input-row:last-child {

  background: #fff;

}

.mui-input-row {

  margin-top: 20px;

  background: #fff;

}

.mui-input-row label ~ input,

.mui-input-row label ~ select,

.mui-input-row label ~ textarea {

  width: 78%;

}

.link-area {

  display: block;

  margin-top: 25px;

  text-align: center;

}

.mui-content-padded {

  margin-top: 30px;

}

</style>

896bd9b5dad6477eb832d08fc9cf6919.png

3.实现登录功能

src\pages\user\Login.vue

login () {

  if (this.loginForm.username === '' || this.loginForm.password === ''){

    this.$toast('账号或密码不能为空')

  } else {

    this.$http.post('login', this.loginForm).then(res => {

      if (res.data.code === 0) {

        this.$toast(res.data.msg)

      } else {

        // 登录成功

      }

    }).catch(() => {

      this.$toast('登录失败')

    })

  }

}

登录成功以后,将用户信息通过store保存。

src\store\modules\user.js

const state = {

  id: 0,

  username: ''

}

const getters = {}

const actions = {}

const mutations = {

  setUser (state, user) {

    state.id = user.id

    state.username = user.username

  }

}

export default {

  namespaced: true,

  state,

  getters,

  actions,

  mutations

}

src\store\index.js

import Vue from 'vue'

import Vuex from 'vuex'

import user from './modules/user'

Vue.use(Vuex)

export default new Vuex.Store({

  modules: {

    user

  }

})

src\pages\user\Login.vue

// 登录成功

this.$store.commit('user/setUser', res.data.data)

this.$toast(res.data.msg)

this.$router.replace({ name: 'user' })

判断是否已经登录

src\store\modules\user.js

const getters = {

  isLogin (state) {

    return state.id !== 0

  }

}

src\pages\User.vue

<script>

import { mapGetters, mapState } from 'vuex'

export default {

  computed: {

    ...mapState({

      username: state => state.user.username

    }),

    ...mapGetters('user', { isLogin: 'isLogin' })

  }

}

</script>

<template>

  <!-- 已登录 -->

  <div v-if="isLogin">

    <div class="member">

      <div class="header-con">

        <div class="user-info">

          <div class="avatar-con">

            <div class="avatar">

              <img src="../assets/images/avatar_default.png" class="image-info">

            </div>

          </div>

          <div class="person-con">

            <span>{{ username }}</span>

          </div>

        </div>

      </div>

    </div>

  </div>

  <!-- 未登录 -->

  <div v-else>

    <div class="member">

       ……(原有代码)

    </div>

  </div>

</template>

4.登录接口和浏览器允许跨域

1、确保后台tpadmin项目安装部署正常,API接口可用

2、设置chrome浏览器,允许跨域访问。新版chrome浏览器的跨域设置(版本号49起):

在chrome浏览器属性页面中的“目标”输入框里加上:

--disable-web-security --user-data-dir=C:\MyChromeDevUserData

2ca59e3fa2594213b543cc24c7581ac2.png

  1. 点击应用和确定后关闭属性页面,并打开 chrome 浏览器。发现有“--disable-web-security”相关的提示,说明 chrome 已经可以正常跨域工作了。745132e64b914d7e8a4d9fcc26b2b901.png

  1. 测试登录效果

未登录效果:

94983c16c3794288bbd3756209cdfa37.png

已登录效果:(用户名test,密码123456)

d5b660bab28f4a7bb35f2ad26b83c60c.png

5.记住登录状态

登录成功以后,记住登录状态

src\auth.js

var auth = {

  getAuthorization () {

    return localStorage.getItem('Authorization');

  },

  setAuthorization (Authorization) {

    localStorage.setItem('Authorization', Authorization);

  }

}

export default {

  install: function (vue) {

    vue.prototype.$auth = auth

  }

}

添加到src\main.js

Vue.config.productionTip = false

import auth from './auth.js'

Vue.use(auth)

import axios from './axios.js'

Vue.use(axios)

注意一定要在axios前面引入auth。

src\pages\user\Login.vue

// 登录成功

this.$store.commit('user/setUser', res.data.data)

this.$auth.setAuthorization(res.data.data.session_id)

this.$toast(res.data.msg)

this.$router.replace({ name: 'user' })

src\axios.js

将保存的session_id放入到下次请求的header中。

export default {

  install: function (vue) {

    var auth = vue.prototype.$auth

    var obj = axios.create({

      baseURL: config.baseURL

    })

    obj.interceptors.request.use(function (conf) {

      conf.headers.Authorization = auth.getAuthorization()

      return conf

    })

    vue.prototype.$http = obj

  }

}

在下次刷新后,获取已登录的用户信息。

将代码写在src\App.vue中。

created () {

  this.showBack = this.$route.path !== '/home'

  this.checkLogin()

},

methods: {

  goBack() {

    this.$router.go(-1)

  },

  checkLogin() {

    this.$indicator.open({

      text: '加载中'

    })

    this.$http.get('user').then(res => {

      if (res.data.code === 1) {

        this.$store.commit('user/setUser', res.data.data)

      }

      this.$indicator.close()

    })

  }

},

访问测试。

重新登录用户,观察在页面刷新后,是否能够自动进行登录。

6.用户菜单

找到已登录的代码。

src\pages\User.vue

<!-- 已登录 -->

<div v-if="isLogin">

  <div class="member">

    ……(原有代码)

  </div>

   <ul class="mui-table-view mui-table-view-chevron">

              <li class="mui-table-view-cell mui-media">

                     <div class="mui-navigate-right">

                           <img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png" />

                      <div class="mui-media-body">我的订单</div>

                         

                  </div>

                   </li>

              <li class="mui-table-view-cell mui-media">

                     <div class="mui-navigate-right">

                           <img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png" />

                      <div class="mui-media-body">收货地址</div>

                         

                  </div>

                   </li>

              <li class="mui-table-view-cell mui-media">

                     <div class="mui-navigate-right">

                          <img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png" />

                      <div class="mui-media-body">退出登录</div>

                  </div>

              </li>

         </ul>

</div>

样式:

<style lang="scss" scoped>

.mui-table-view .mui-media,

.mui-table-view .mui-media-body {

  line-height: 42px;

}

.mui-table-view-cell:after {

  left: 0px;

}

……(原有代码)

</style>

效果:

f3b49bc87afb4b5a93082d085a10d4f4.png

7.退出登录

src\pages\User.vue

<div @click="logout" class="mui-navigate-right">

  <img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png">

  <div class="mui-media-body">退出登录</div>

</div>

export default {

     computed: {

         ...mapState({

              username: state => state.user.username

         }),

         ...mapGetters('user', {

              isLogin: 'isLogin'

         })

     },

     methods: {

       logout () {

         this.$http.get('logout')

         this.$store.commit('user/logout')

         this.$auth.setAuthorization('')

         this.$toast('退出成功')

       }

     }

}

src\store\modules\user.js

const mutations = {

 ……(原有代码)

  logout (state) {

    state.id = 0

    state.username = ''

  }

}

服务测试,当单击“退出登录”以后,页面会变成未登录的状态:

4fa5ae8d27964274ab43f1f45cbde198.png

7.注册页面

注册路由:

src\router.js

import Register from './pages/user/Register.vue'

routes: [

  ……(原有代码)

  { path: '/user/register', component: Register, name: 'register', meta: { title: '注册' } }

],

src\pages\user\Register.vue

<template>

  <div>

    <div class="mui-content">

      <form class="mui-input-group">

        <div class="mui-input-row">

          <label>账号</label>

          <input v-model="regForm.username" type="text" class="mui-input-clear mui-input" placeholder="请输入账号">

        </div>

        <div class="mui-input-row">

          <label>密码</label>

          <input v-model="regForm.password" type="password" class="mui-input-clear mui-input" placeholder="请输入密码">

        </div>

        <div class="mui-input-row">

          <label>确认</label>

          <input type="password" ref="pwdConfirm" class="mui-input-clear mui-input" placeholder="请确认密码">

        </div>

        <div class="mui-input-row">

          <label>邮箱</label>

          <input v-model="regForm.email" type="email" class="mui-input-clear mui-input" placeholder="请输入邮箱">

        </div>

      </form>

      <div class="mui-content-padded">

        <button @click="register" class="mui-btn mui-btn-block mui-btn-primary">注册</button>

      </div>

      <div class="mui-content-padded">

        <p>注册成功后的用户可用于登录</p>

      </div>

    </div>

  </div>

</template>

数据绑定:

<script>

export default {

  data () {

    return {

      regForm: {

        username: '',

        password: '',

        email: ''

      }

    }

  },

  methods: {

    register: function () {

    }

  }

}

</script>

样式:

<style lang="scss" scoped>

.mui-input-group {

  margin-top: 10px;

  background-color: transparent;

}

.mui-input-group label {

  width: 22%;

}

.mui-input-row:last-child {

  background: #fff;

}

.mui-input-row {

  margin-top: 20px;

  background: #fff;

}

.mui-input-row label ~ input,

.mui-input-row label ~ select,

.mui-input-row label ~ textarea {

  width: 78%;

}

.link-area {

  display: block;

  margin-top: 25px;

  text-align: center;

}

.mui-content-padded {

  margin-top: 30px;

}

</style>

访问测试:

6e904f5524e0446a84d29e4d255f76ca.png

提交表单

register: function () {

  var pwdConfirm = this.$refs.pwdConfirm.value

  if (this.regForm.username === '') {

    this.$toast('账号不能为空')

    return

  } else if (this.regForm.password === '') {

    this.$toast('密码不能为空')

     return

  } else if (this.regForm.password != pwdConfirm) {

    this.$toast('密码两次输入不一致')

    return

  } else if (this.regForm.email === '') {

    this.$toast('邮箱不能为空')

    return

  }

  console.log(this.regForm)

}

控制台输出结果:

a1f48b074a324ae0aefdace0b578d874.png

8.注册接口

确保后台tpadmin项目安装部署正常,API接口可用

9.实现注册功能

提交注册表单:

src\pages\user\Register.vue

console.log(this.regForm)

this.$indicator.open({

  text: '注册中'

})

this.$http.post('register', this.regForm).then(res => {

  this.$indicator.close()

  if (res.data.code === 0) {

    this.$toast(res.data.msg)

  } else {

    this.$store.commit('user/setUser', res.data.data)

    this.$auth.setAuthorization(res.data.data.session_id)

    this.$toast(res.data.msg)

    this.$router.replace({ name: 'user' })

  }

}).catch(() => {

  this.$toast('注册失败')

})

访问测试:

输入用户名和密码,点击注册。

注册完成后:

f39e1a4c69a14aa28295ede0d5396e7a.png

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值