仿美团pc,koa+ssr(二)

一,注册和登录功能

pages-->新建register.vue 注册组件

注:md5加密,crypto-js加密库

<template>
  <div class="page-register">
    <article class="header">
      <header>
        <a
          href="/"
          class="site-logo" />
        <span class="login">
          <em class="bold">已有美团账号?</em>
          <a href="/login">
            <el-button
              type="primary"
              size="small">登录</el-button>
          </a>
        </span>
      </header>
    </article>
    <!-- 注册页 -->
    <section>
      <el-form
        ref="ruleForm"
        :model="ruleForm"
        :rules="rules"
        label-width="100px"
        class="demo-ruleForm">
        <el-form-item
          label="昵称"
          prop="name">
          <el-input v-model="ruleForm.name" />
        </el-form-item>
        <el-form-item
          label="邮箱"
          prop="email">
          <el-input v-model="ruleForm.email" />
          <el-button
            size="mini"
            round
            @click="sendMsg">发送验证码</el-button>
            <!-- 提示错误信息 -->
          <span class="status">{{ statusMsg }}</span>
        </el-form-item>
        <el-form-item
          label="验证码"
          prop="code">
          <el-input
            v-model="ruleForm.code"
            maxlength="4" />
        </el-form-item>
        <el-form-item
          label="密码"
          prop="pwd">
          <el-input
            v-model="ruleForm.pwd"
            type="password" />
        </el-form-item>
        <el-form-item
          label="确认密码"
          prop="cpwd">
          <el-input
            v-model="ruleForm.cpwd"
            type="password" />
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            @click="register">同意以下协议并注册</el-button>
            <!-- 错误提示 -->
          <div class="error">{{ error }}</div>
        </el-form-item>
        <el-form-item>
          <a
            class="f1"
            href="http://www.meituan.com/about/terms"
            target="_blank">《美团网用户协议》</a>
        </el-form-item>
      </el-form>
    </section>
  </div>
</template>

<script>
import CryptoJS from 'crypto-js'
        export default {
          data() {
            return {
              statusMsg: '',
              error: '',
              ruleForm: {
                name: '',
                code: '',
                pwd: '',
                cpwd: '',
                email: ''
              },
              // 验证规则属性
              rules: {
                name: [{
                  required: true,
                  type: 'string',
                  message: '请输入昵称',
                  trigger: 'blur'
                }],
                email: [{
                  required: true,
                  type: 'email',
                  message: '请输入邮箱',
                  trigger: 'blur'
                }],
                pwd: [{
                  required: true,
                  message: '创建密码',
                  trigger: 'blur'
                }],
                cpwd: [{
                  required: true,
                  message: '确认密码',
                  trigger: 'blur'
                }, {
                  // 自定义验证规则
                  validator: (rule, value, callback) => {
                    if (value === '') {
                      callback(new Error('请再次输入密码'))
                    } else if (value !== this.ruleForm.pwd) {
                      callback(new Error('两次输入密码不一致'))
                    } else {
                      callback()
                    }
                  },
                  trigger: 'blur'
                }]
              }
            }
          },
          // 公用模板组件
          layout: 'blank',
          methods: {
            // 点击发送验证码
            sendMsg: function () {
              const self = this;
              let namePass
              let emailPass
              if (self.timerid) {
                return false
              }
              this.$refs['ruleForm'].validateField('name', (valid) => {
                namePass = valid
              })
              self.statusMsg = ''
              if (namePass) {
                return false
              }
              this.$refs['ruleForm'].validateField('email', (valid) => {
                emailPass = valid
              })
              // 验证成功,发送验证码请求
              if (!namePass && !emailPass) {
                self.$axios.post('/users/verify', {
                  // 中文编码
                  username: encodeURIComponent(self.ruleForm.name),
                  email: self.ruleForm.email
                }).then(({
                  status,
                  data
                }) => {
                  if (status === 200 && data && data.code === 0) {
                    let count = 60;
                    self.statusMsg = `验证码已发送,剩余${count--}秒`
                    self.timerid = setInterval(function () {
                      self.statusMsg = `验证码已发送,剩余${count--}秒`
                      if (count === 0) {
                        clearInterval(self.timerid)
                      }
                    }, 1000)
                  } else {
                    self.statusMsg = data.msg
                  }
                })
              }
            },
            // 点击注册按钮
            register: function () {
              let self = this;
              // 验证全部通过,发送注册请求
              this.$refs['ruleForm'].validate((valid) => {
                if (valid) {
                  self.$axios.post('/users/signup', {
                    username: window.encodeURIComponent(self.ruleForm.name),
                    // md5加密
                    password: CryptoJS.MD5(self.ruleForm.pwd).toString(),
                    email: self.ruleForm.email,
                    code: self.ruleForm.code
                  }).then(({
                    status,
                    data
                  }) => {
                    if (status === 200) {
                      if (data && data.code === 0) {
                        // 强制跳转到登录页
                        location.href = '/login'
                      } else {
                        self.error = data.msg
                      }
                    } else {
                      self.error = `服务器出错,错误码:${status}`
                    }
                    setTimeout(function () {
                      self.error = ''
                    }, 1500)
                  })
                }
              })
            }
          }
        }
</script>

<style lang="scss">
@import "@/assets/css/register/index.scss";
</style>

layout-->新建blank.vue模板

<template>
  <div class="layout-blank">
    <nuxt/>
  </div>
</template>

<script>
export default {
}
</script>

<style lang="css">
</style>

pages-->新建login.vue 登录组件,服务端已做了本地化持久存储功能,前端不需要做

<template>
  <div class="page-login">
    <div class="login-header">
      <a
        href="/"
        class="logo"/>
    </div>
    <div class="login-panel">
      <div class="banner">
        <img
          src="//s0.meituan.net/bs/file/?f=fe-sso-fs:build/page/static/banner/www.jpg"
          width="480"
          height="370"
          alt="美团网">
      </div>
      <div class="form">
        <h4
          v-if="error"
          class="tips"><i/>{{ error }}</h4>
        <p><span>账号登录</span></p>
        <el-input
          v-model="username"
          prefix-icon="profile"/>
        <el-input
          v-model="password"
          prefix-icon="password"
          type="password"/>
        <div class="foot">
          <el-checkbox v-model="checked">7天内自动登录</el-checkbox>
          <b>忘记密码?</b>
        </div>
        <el-button
          class="btn-login"
          type="success"
          size="mini"
          @click="login">登录</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import CryptoJS from 'crypto-js'
export default {
  data: () => {
    return {
      checked: '',
      username: '',
      password: '',
      error: ''
    }
  },
  layout: 'blank',
  methods: {
    login: function () {
      let self=this;
      self.$axios.post('/users/signin',{
        username:window.encodeURIComponent(self.username),
        password:CryptoJS.MD5(self.password).toString()
      }).then(({status,data})=>{
        if(status===200){
          if(data&&data.code===0){
            location.href='/'
          }else{
            self.error=data.msg
          }
        }else{
          self.error=`服务器出错`
        }
      })
    }
  }
}
</script>

<style lang="scss">
    @import "@/assets/css/login/index.scss";
</style>

components->public->header->user.vue,顶部组件用户信息改造

<template>
  <div class="m-user">
    <template v-if="user">
      欢迎您,<span class="username">{{ user }}</span>
      [<nuxt-link to="/exit">退出</nuxt-link>]
    </template>
    <template v-else>
      <nuxt-link
        to="/login"
        class="login">立即登录</nuxt-link>
      <nuxt-link
        class="register"
        to="/register">注册</nuxt-link>
    </template>
  </div>
</template>

<script>
export default {
  data(){
    return {
      user:''
    }
  },
  async mounted(){
    const {status,data:{user}} = await this.$axios.get('/users/getUser')
    if(status===200){
      this.user=user
    }
  }
}
</script>

<style lang="css">
</style>

pages->新建exit.vue组件,退出功能

<template>
  <div class=""/>
</template>

<script>
export default {
  layout: 'blank',
  // 利用中间件,到达页面自动执行以下逻辑
  middleware: async (ctx) => {
    let {status,data}=await ctx.$axios.get('/users/exit')
    if(status===200&&data&&data.code===0){
      window.location.href='/'
    }
  }
}
</script>
原文地址:https://www.cnblogs.com/fsg6/p/14427669.html