zoukankan      html  css  js  c++  java
  • 使用vue搭建应用六实现登录页

    1.js_cookie

    js-cookie插件是一个JS操作cookie的插件

    安装

    yarn add js-cookie

     使用

      写入 Cookies.set('name', 'value');

      读取 Cookies.get('name');

      删除 Cookies.remove('name');

    2.http请求

    (1)模块封装

      在src下添加目录 utils,添加 global.js

    /**
     * 全局常量、方法封装模块
     * 通过原型挂载到Vue属性
     * 通过 this.Global 调用
     */
    export const baseUrl = 'http://localhost:8081'
    
    export default {
      baseUrl
    }

      在src下添加目录 http

      config.js

    import { baseUrl } from '@/utils/global'
    
    export default {
      method: 'get',
      // 基础url前缀
      baseUrl: baseUrl,
      // 请求头信息
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
      // 参数
      data: {},
      // 设置超时时间
      timeout: 10000,
      // 携带凭证
      withCredentials: true,
      // 返回数据类型
      responseType: 'json'
    }
    View Code

      axios.js axios封装

    import axios from 'axios';
    import config from './config';
    import Cookies from "js-cookie";
    import router from '@/router'
    
    export default function $axios(options) {
      return new Promise((resolve, reject) => {
        const instance = axios.create({
          baseURL: config.baseUrl,
          headers: config.headers,
          timeout: config.timeout,
          withCredentials: config.withCredentials
        })
        // request 请求拦截器
        instance.interceptors.request.use(
          config => {
            let token = Cookies.get('token')
            // 发送请求时携带token
            if (token) {
              config.headers.token = token
            } else {
              // 重定向到登录页面
              router.push('/login')
            }
            return config
          },
          error => {
            // 请求发生错误时
            console.log('request:', error)
            // 判断请求超时
            if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
              console.log('timeout请求超时')
            }
            // 需要重定向到错误页面
            const errorInfo = error.response
            console.log(errorInfo)
            if (errorInfo) {
              error = errorInfo.data  // 页面那边catch的时候就能拿到详细的错误信息,看最下边的Promise.reject
              const errorStatus = errorInfo.status; // 404 403 500 ...
              router.push({
                path: `/error/${errorStatus}`
              })
            }
            return Promise.reject(error) // 在调用的那边可以拿到(catch)你想返回的错误信息
          }
        )
    
        // response 响应拦截器
        instance.interceptors.response.use(
          response => {
            return response.data
          },
          err => {
            if (err && err.response) {
              switch (err.response.status) {
                case 400:
                  err.message = '请求错误'
                  break
                case 401:
                  err.message = '未授权,请登录'
                  break
                case 403:
                  err.message = '拒绝访问'
                  break
                case 404:
                  err.message = `请求地址出错: ${err.response.config.url}`
                  break
                case 408:
                  err.message = '请求超时'
                  break
                case 500:
                  err.message = '服务器内部错误'
                  break
                case 501:
                  err.message = '服务未实现'
                  break
                case 502:
                  err.message = '网关错误'
                  break
                case 503:
                  err.message = '服务不可用'
                  break
                case 504:
                  err.message = '网关超时'
                  break
                case 505:
                  err.message = 'HTTP版本不受支持'
                  break
                default:
              }
            }
            console.error(err)
            return Promise.reject(err) // 返回接口返回的错误信息
          }
        )
        // 请求处理
        instance(options).then(res => {
          resolve(res)
          return false
        }).catch(error => {
          reject(error)
        })
      })
    }
    View Code

      modules/login.js  系统登录模块

    // 登录接口
    export function login() {
    
      const loginData = {
        "code": 304,
        "msg": "登录失败",
        "data": {
          "id": 1,
          "userId": 1,
          "token": "1111111111"
        }
      }
      /*
      const loginData = {
        "code": 200,
        "msg": "登录成功",
        "data": {
          "id": 1,
          "userId": 1,
          "token": "1111111111"
        }
      }
      */
      return {
        url: 'login',
        type: 'post',
        data: loginData
      }
    }
    // 登出接口
    export function logout() {
      const logoutData = {
        "code": 200,
        "msg": null,
        "data": {
        }
      }
      return {
        url: 'logout',
        type: 'get',
        data: logoutData
      }
    }
    View Code

      api.js 接口统一集成模块

    import * as login from './modules/login'
    
    export default {
      login
    }
    View Code

      index.js  导入所有接口

    import api from './api'
    
    const install = Vue => {
      if (install.installed)
        return;
    
      install.installed = true;
    
      Object.defineProperties(Vue.prototype, {
        // 注意,此处挂载在 Vue 原型的 $api 对象上
        $api: {
          get() {
            return api
          }
        }
      })
    }
    
    export default install

    (2)应用

      main.js

    webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import api from './http'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    
    Vue.config.productionTip = false
    
    Vue.use(ElementUI)
    Vue.use(api)  // 注册使用API模块
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      render: h => h(App)
    })

    3.登录

      view/login.vue

    <template>
      <el-form
        :model="loginForm"
        :rules="fieldRules"
        ref="loginForm"
        label-position="left"
        label-width="0px"
        class="demo-ruleForm login-container"
      >
        <span class="tool-bar"></span>
        <h2 class="title" style="padding-left:22px;">系统登录</h2>
        <el-form-item prop="account">
          <el-input type="text" v-model="loginForm.account" auto-complete="off" placeholder="账号"></el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input type="password" v-model="loginForm.password" auto-complete="off" placeholder="密码"></el-input>
        </el-form-item>
        <el-form-item style="100%;">
          <el-button type="primary" style="48%;" @click.native.prevent="reset">重 置</el-button>
          <el-button
            type="primary"
            style="48%;"
            @click.native.prevent="login"
            :loading="loading"
          >登 录</el-button>
        </el-form-item>
      </el-form>
    </template>
    
    <script>
    import Cookies from "js-cookie";
    export default {
      name: "Login",
      data() {
        return {
          loading: false,
          loginForm: {
            account: "admin",
            password: "admin"
          },
          fieldRules: {
            account: [{ required: true, message: "请输入账号", trigger: "blur" }],
            password: [{ required: true, message: "请输入密码", trigger: "blur" }]
          },
          checked: true
        };
      },
      methods: {
        login() {
          this.loading = true;
          let userInfo = {
            account: this.loginForm.account,
            password: this.loginForm.password
          };
          this.$api.login
            .login(userInfo)
            .then(res => {
              // 调用登录接口
              if (res.code != 200) {
                this.$message({ message: res.msg, type: "error" });
              } else {
                this.$message({ message: res.msg, type: "success" });
                console.log(res);
                Cookies.set("token", res.data.token); // 放置token到Cookie
                sessionStorage.setItem("user", userInfo.account); // 保存用户到本地会话
                this.$router.push("/"); // 登录成功,跳转到主页
              }
              this.loading = false;
            })
            .catch(res => {
              this.$message({ message: res.message, type: "error" });
            });
        },
        reset() {
          this.$refs.loginForm.resetFields();
        }
      }
    };
    </script>
    
    <style lang="scss" scoped>
    .login-container {
      -webkit-border-radius: 5px;
      border-radius: 5px;
      -moz-border-radius: 5px;
      background-clip: padding-box;
      margin: 100px auto;
       350px;
      padding: 35px 35px 15px 35px;
      background: #fff;
      border: 1px solid #eaeaea;
      box-shadow: 0 0 25px #cac6c6;
      .title {
        margin: 0px auto 30px auto;
        text-align: center;
        color: #505458;
      }
    }
    </style>
    View Code

    4.测试

    mock封装

      在src下添加目录 mock

      index.js

    import Mock from 'mockjs'
    import { baseUrl } from '@/utils/global'
    import * as login from './modules/login'
    
    // 1. 开启/关闭[所有模块]拦截, 通过调[openMock参数]设置.
    // 2. 开启/关闭[业务模块]拦截, 通过调用fnCreate方法[isOpen参数]设置.
    // 3. 开启/关闭[业务模块中某个请求]拦截, 通过函数返回对象中的[isOpen属性]设置.
    let openMock = true
    // let openMock = false
    fnCreate(login, openMock)
    
    /**
     * 创建mock模拟数据
     * @param {*} mod 模块
     * @param {*} isOpen 是否开启?
     */
    function fnCreate(mod, isOpen = true) {
    
      if (isOpen) {
        for (var key in mod) {
          ((res) => {
            if (res.isOpen !== false) {
              let url = baseUrl
              if (!url.endsWith("/")) {
                url = url + "/"
              }
              url = url + res.url
              Mock.mock(new RegExp(url), res.type, (opts) => {
                opts['data'] = opts.body ? JSON.parse(opts.body) : null
                delete opts.body
                console.log('
    ')
                console.log('%cmock拦截, 请求: ', 'color:blue', opts)
                console.log('%cmock拦截, 响应: ', 'color:blue', res.data)
                return res.data
              })
            }
          })(mod[key]() || {})
        }
      }
    }
    View Code

    modules/login.js  系统登录模块

    // 登录接口
    export function login() {
    
      const loginData = {
        "code": 304,
        "msg": "登录失败",
        "data": null
      }
      return {
        url: 'login',
        type: 'post',
        data: loginData
      }
    }

    启动执行 npm  run dev

    浏览器打开 http://localhost:8080/#/login

     

     修改modules/login.js

    // 登录接口
    export function login() {
      const loginData = {
        "code": 200,
        "msg": "登录成功",
        "data": {
          "id": 1,
          "userId": 1,
          "token": "1111111111"
        }
      }
      return {
        url: 'login',
        type: 'post',
        data: loginData
      }
    }

  • 相关阅读:
    A Complete Guide to the <Picture> Element
    html5 在移动端的缩放控制
    新版itunes添加铃声
    html5 背景音乐 js控制播放 暂停
    thinkphp mysql 坐标按距离排序
    jquery ajax跨域 thinkphp getjson
    webkit-box
    Javascript 获取页面高度(多种浏览器)
    怎样实现iMessage群发
    css3背景透明文字不透明
  • 原文地址:https://www.cnblogs.com/baby123/p/11868994.html
Copyright © 2011-2022 走看看