尚品汇注册登录实现

需要源码请私我,因为该资源已存在,无法上传到我的资源中

尚硅谷课程“尚品汇”注册登录页实现

注册页

配置路由

  1. 在src目录下新建pages-组件/router-路由/
    1. 注册和登录、首页组件路由配置
    • 新建router文件夹存放路由配置信息以及暴露路由

    • 在routes文件中引入路由组件,配置路由信息并对外暴露
      在这里插入图片描述

    • 在index.js中注册路由
      在这里插入图片描述

    • 在main.js中注册路由
      在这里插入图片描述

    • 在App.vue中设置路由出口
      在这里插入图片描述

    • 最终效果:在地址栏输入对应的路由信息即可跳转在这里插入图片描述

完成静态页面

  1. 注册页面静态实现
    1. 在register.vue中
    • 框架
<template>
  <div class="register-container">
    <!-- 注册内容 -->
    <div class="register">
      <h3>注册新用户
        <span class="go">我有账号,去 <a href="login.html" target="_blank">登陆</a>
        </span>
      </h3>
      <div class="content">
        <label>手机号:</label>
        <input type="text" placeholder="请输入你的手机号">
        <span class="error-msg">错误提示信息</span>
      </div>
      <div class="content">
        <label>验证码:</label>
        <input type="text" placeholder="请输入验证码">
        <button>获取验证码</button>
        <span class="error-msg">错误提示信息</span>
      </div>
      <div class="content">
        <label>登录密码:</label>
        <input type="text" placeholder="请输入你的登录密码">
        <span class="error-msg">错误提示信息</span>
      </div>
      <div class="content">
        <label>确认密码:</label>
        <input type="text" placeholder="请输入确认密码">
        <span class="error-msg">错误提示信息</span>
      </div>
      <div class="controls">
        <input name="m1" type="checkbox">
        <span>同意协议并注册《尚品汇用户协议》</span>
        <span class="error-msg">错误提示信息</span>
      </div>
      <div class="btn">
        <button>完成注册</button>
      </div>
    </div>

    <!-- 底部 -->
    <div class="copyright">
      <ul>
        <li>关于我们</li>
        <li>联系我们</li>
        <li>联系客服</li>
        <li>商家入驻</li>
        <li>营销中心</li>
        <li>手机尚品汇</li>
        <li>销售联盟</li>
        <li>尚品汇社区</li>
      </ul>
      <div class="address">地址:北京市昌平区宏福科技园综合楼6层</div>
      <div class="beian">京ICP备19006430号
      </div>
    </div>
  </div>
</template>

  • 样式(使用less预编译)
<style lang="less" scoped>
  .register-container {
    .register {
      width: 1200px;
      height: 445px;
      border: 1px solid rgb(223, 223, 223);
      margin: 0 auto;

      h3 {
        background: #ececec;
        margin: 0;
        padding: 6px 15px;
        color: #333;
        border-bottom: 1px solid #dfdfdf;
        font-size: 20.04px;
        line-height: 30.06px;

        span {
          font-size: 14px;
          float: right;

          a {
            color: #e1251b;
          }
        }
      }

      div:nth-of-type(1) {
        margin-top: 40px;
      }

      .content {
        padding-left: 390px;
        margin-bottom: 18px;
        position: relative;

        label {
          font-size: 14px;
          width: 96px;
          text-align: right;
          display: inline-block;
        }

        input {
          width: 270px;
          height: 38px;
          padding-left: 8px;
          box-sizing: border-box;
          margin-left: 5px;
          outline: none;
          border: 1px solid #999;
        }

        img {
          vertical-align: sub;
        }

        .error-msg {
          position: absolute;
          top: 100%;
          left: 495px;
          color: red;
        }
      }

      .controls {
        text-align: center;
        position: relative;

        input {
          vertical-align: middle;
        }

        .error-msg {
          position: absolute;
          top: 100%;
          left: 495px;
          color: red;
        }
      }

      .btn {
        text-align: center;
        line-height: 36px;
        margin: 17px 0 0 55px;

        button {
          outline: none;
          width: 270px;
          height: 36px;
          background: #e1251b;
          color: #fff !important;
          display: inline-block;
          font-size: 16px;
        }
      }
    }

    .copyright {
      width: 1200px;
      margin: 0 auto;
      text-align: center;
      line-height: 24px;

      ul {
        li {
          display: inline-block;
          border-right: 1px solid #e4e4e4;
          padding: 0 20px;
          margin: 15px 0;
        }
      }
    }
  }
</style>

注意:出现以下报错
在这里插入图片描述

由于使用了less语法,缺失了less-loader;安装less/less-loader依赖即可解决报错
效果在这里插入图片描述


请求接口

  1. 接口封装
    1. 在src目录下新建api文件夹
    2. 在api目录下新建requests.js(axios二次封装)
    • 安装axios依赖
    • 封装axios

import axios from "axios";

// 对axios二次封装
const requests = axios({
  baseURL: '/api',
  timeout: 5000
})

// 设置请求拦截器
requests.interceptors.request.use((config) => {
  return config
})

// 设置响应拦截器
requests.interceptors.response.use((res) => {
  return res.data
}, (error) => {
  console.log(error);
  return Promise.reject(new Error('faile'))
})

// 对外暴露
export default requests

  1. 在api目录下新建index.js(请求定制)

  2. 在vue.config.js中设置代理跨域。

  • 注意:每次写完配置文件后要重新启动服务
// 代理跨域
  devServer: {
    proxy: {
      '/api': {
        // target是目标请求URL
        target: 'http://gmall-h5-api.atguigu.cn',
      }
    }
  }
  1. 在api/index.js中定制注册页相关请求
    1. 获取验证码:
export const reqGetCode = (phone) => requests({
url: `/user/passport/sendCode/${phone}`,
method: 'GET'
 })
  1. 注册请求
// 注册请求
export const reqRegisterUser = (data) => requests({
url: '/user/passport/register',
method: 'POST',
data
})

  1. 获取注册页的表单内容

    • 在data内声明表单元素
    data() {
     return {
       // 表单数据
       // 手机号
       phone: '',
       // 验证码
       code: '',
       // 密码
       password: '',
       // 确认密码
       repassword: ''
     };
    },
    
    • 使用v-model响应式绑定数据框,获取用户输入数据
     <input v-model="phone" type="text" placeholder="请输入你的手机号">
     <input v-model="code" type="text" placeholder="请输入验证码">
     密码与上面一致
    
    • 效果在这里插入图片描述

    组件身上data属性有了响应的响应式数据。

  2. 在src目录下新建store文件夹,用于存放组件的仓库

    1. 新建user.js文件,用于存放于用户相关的信息
    // 导入获取验证码的请求
     import { reqGetCode } from '@/api/index'
    
     // 存放数据
     const state = {}
    
     // 修改state的
     const mutations = {}
    
     // 提交mutations,异步操作
     const actions = {
       // 获取验证码 
       // commit:占位,用于派发mutations;phone:请求的参数
       getCode({ commit }, phone) {
         let result = reqGetCode(phone)
         console.log(result);
       }
     }
    
     // 对state内数据的计算
     const getters = {}
    
     // 对外暴露
     export default {
       state,
       mutations,
       actions,
       getters
     }
    
    1. 在store目录下新建index.js文件,用作大仓库
       import Vue from 'vue'
     import Vuex from 'vuex'
     // 使用插件
     Vue.use(Vuex)
    
     // 导入小仓库
     import user from './User/user'
    
     // 对外暴露store的一个类的实例
     export default new Vuex.Store({
       modules: {
         // 小仓库
         user
       }
     })
    
    1. 在main.js中注册大仓库
       // 引入仓库
     import store from './store'
    
     new Vue({
       render: h => h(App),
       // 注册路由信息
       router,
       // 注册仓库
       store
     }).$mount('#app')
    
    

    效果在这里插入图片描述


  1. 获取验证码

    • 在register.vue组件中给’获取验证码’按钮添加点击事件。在method中派发actions
      <button @click="getCode">获取验证码</button>
    
       methods: {
     // 获取验证码
     getCode() {
       const { phone } = this
       // 派发actions
       this.$store.dispatch('getCode', phone)
     }
     },
    

    效果在这里插入图片描述

    • 将返回的验证码存到user仓库在这里插入图片描述

  1. 将仓库中的code直接显示在‘获取验证码’的input框中。在register组件中的methods方法内修改getCode方法
  // 获取验证码
  async getCode() {
  // try等待派发的actions返回成功的Promise后,直接修改code值
  try {
    const { phone } = this
    // 派发actions
    await this.$store.dispatch('getCode', phone)
    this.code = this.$store.state.user.code
    } catch (error) {
      console.log('获取失败');
    }
  }

效果在这里插入图片描述

  1. 注册请求

    1. 在user仓库中调用注册请求
      async registerUserInfo({ commit }, data) {
      let result = await reqRegisterUser(data)
      // 当结果200代表成功
      if (result.code == 200) {
        return 'ok'
      } else {
        return Promise.reject(new Error('faile'))
      }
    }
    
    1. 给‘完成注册’按钮添加点击事件
    • <button @click="register">完成注册</button>
    1. 在methods中写该方法
        // 注册请求
    async register() {
      try {
        const { phone, code, password } = this
        // 派发注册请求的actions
        await this.$store.dispatch('registerUserInfo', { phone, code, password })
        // 注册结果返回成功后跳转到登录页面
        this.$router.push('/login')
      } catch (error) {
        console.log(error);
      }
    }
    

    效果在这里插入图片描述

登录页

  1. 完成静态页面,在login.vue组件中
    • 搭建框架
  <template>
  <div class="login-container">
    <!-- 登录 -->
    <div class="login-wrap">
      <div class="login">
        <div class="loginform">
          <ul class="tab clearFix">
            <li>
              <a href="##" style="border-right: 0;">扫描登录</a>
            </li>
            <li>
              <a href="##" class="current">账户登录</a>
            </li>
          </ul>

          <div class="content">
            <form action="##">
              <div class="input-text clearFix">
                <span></span>
                <input type="text" placeholder="邮箱/用户名/手机号">
              </div>
              <div class="input-text clearFix">
                <span class="pwd"></span>
                <input type="text" placeholder="请输入密码">
              </div>
              <div class="setting clearFix">
                <label class="checkbox inline">
                  <input name="m1" type="checkbox" value="2" checked="">
                  自动登录
                </label>
                <span class="forget">忘记密码?</span>
              </div>
              <button class="btn">登&nbsp;&nbsp;录</button>
            </form>

            <div class="call clearFix">
              <ul>
                <li><img src="./images/qq.png" alt=""></li>
                <li><img src="./images/sina.png" alt=""></li>
                <li><img src="./images/ali.png" alt=""></li>
                <li><img src="./images/weixin.png" alt=""></li>
              </ul>
              <router-link class="register" to="/register">立即注册</router-link>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 底部 -->
    <div class="copyright">
      <ul>
        <li>关于我们</li>
        <li>联系我们</li>
        <li>联系客服</li>
        <li>商家入驻</li>
        <li>营销中心</li>
        <li>手机尚品汇</li>
        <li>销售联盟</li>
        <li>尚品汇社区</li>
      </ul>
      <div class="address">地址:北京市昌平区宏福科技园综合楼6层</div>
      <div class="beian">京ICP备19006430号
      </div>
    </div>
  </div>
</template>

注意:报错图片资源加载错误在这里插入图片描述

先导入图片资源,在修改图片的src路径即可

  • 引入样式
    <style lang="less" scoped>
  .login-container {
    .login-wrap {
      height: 487px;
      background-color: #e93854;

      .login {
        width: 1200px;
        height: 487px;
        margin: 0 auto;
        background: url(./images/loginbg.png) no-repeat;
      }

      .loginform {
        width: 420px;
        height: 406px;
        box-sizing: border-box;
        background: #fff;
        float: right;
        top: 45px;
        position: relative;
        padding: 20px;

        .tab {

          li {
            width: 50%;
            float: left;
            text-align: center;

            a {
              width: 100%;
              display: block;
              height: 50px;
              line-height: 50px;
              font-size: 20px;
              font-weight: 700;
              color: #333;
              border: 1px solid #ddd;
              box-sizing: border-box;
              text-decoration: none;

            }

            .current {
              border-bottom: none;
              border-top-color: #28a3ef;
              color: #e1251b;
            }
          }
        }

        .content {
          width: 380px;
          height: 316px;
          box-sizing: border-box;
          border: 1px solid #ddd;
          border-top: none;
          padding: 18px;

          form {
            margin: 15px 0 18px 0;
            font-size: 12px;
            line-height: 18px;

            .input-text {
              margin-bottom: 16px;

              span {
                float: left;
                width: 37px;
                height: 32px;
                border: 1px solid #ccc;
                background: url(../../assets/icons.png) no-repeat -10px -201px;
                box-sizing: border-box;
                border-radius: 2px 0 0 2px;
              }

              .pwd {
                background-position: -72px -201px;
              }

              input {
                width: 302px;
                height: 32px;
                box-sizing: border-box;
                border: 1px solid #ccc;
                border-left: none;
                float: left;
                padding-top: 6px;
                padding-bottom: 6px;
                font-size: 14px;
                line-height: 22px;
                padding-right: 8px;
                padding-left: 8px;

                border-radius: 0 2px 2px 0;
                outline: none;
              }
            }

            .setting {
              label {
                float: left;
              }

              .forget {
                float: right;
              }
            }

            .btn {
              background-color: #e1251b;
              padding: 6px;
              border-radius: 0;
              font-size: 16px;
              font-family: 微软雅黑;
              word-spacing: 4px;
              border: 1px solid #e1251b;
              color: #fff;
              width: 100%;
              height: 36px;
              margin-top: 25px;
              outline: none;
            }
          }

          .call {
            margin-top: 30px;

            ul {
              float: left;

              li {
                float: left;
                margin-right: 5px;
              }
            }

            .register {
              float: right;
              font-size: 15px;
              line-height: 38px;
            }

            .register:hover {
              color: #4cb9fc;
              text-decoration: underline;
            }
          }

        }
      }
    }

    .copyright {
      width: 1200px;
      margin: 0 auto;
      text-align: center;
      line-height: 24px;

      ul {
        li {
          display: inline-block;
          border-right: 1px solid #e4e4e4;
          padding: 0 20px;
          margin: 15px 0;
        }
      }
    }

  }
  </style>

效果在这里插入图片描述

  1. 登录请求:这里因为不用接收过多的请求返回结果。所以采用不使用仓库派发actions,直接在组件中派发的方法

    1. 在main.js中导入api,注册为全局事件在这里插入图片描述
  2. 使用v-model获取用户输入,在login.vue组件methods中写登录方法,

         // 登录
     async login() {
       // 将data解构
       const { phone, password } = this
       let result = await this.$API.reqLoginUser({ phone, password })
       // 登录成功
       if (result.code == 200) {
         // 将token和name存到本地
         localStorage.setItem('TOKEN', result.data.token)
         localStorage.setItem('Name', result.data.name)
         // 跳转到首页
         this.$router.push('/')
       } else {
         console.log('登录失败');
       }
     }
    

    注意:登录成功后会返回一个token,存到本地

    • 未存储本地前:在这里插入图片描述

    • 登录成功后存本地结果:在这里插入图片描述

    返回值效果在这里插入图片描述

总结

  1. 重点:
    • 路由跳转传参:使用的是queryparams参数
    • 代理跨域、请求定制
    • 不使用仓库,直接在组件实例中发请求
    • 出自尚硅谷“尚品汇”项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自拍拍到鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值