vue 实现前台用户登录

1、封装登录接口 api,新建 src/api/auth.js ,添加如下代码:

import request from "@/utils/request";

// 登录接口
export function fetchLogin(data) {
  return request({
    url: "/auth/sign_in",
    method: "post",
    data,
  });
}

2、准备登录路由,在 router/index.js 中添加登录的路由

.
import LoginView from "../views/LoginView.vue";
.
{
    path: "/login",
    name: "Login",
    component: LoginView,
},
.
.

3、新建 src/views/LoginView.vue 组件并请求登录接口,添加代码:

<template>
  <div class="wrapper">
    <div class="wrap">
      <div class="layout_panel">
        <div class="layout" id="layout">
          <div id="main-content">
            <div class="mainbox form-panel" id="login-main">
              <div class="lgnheader">
                <div class="header_tit t_c">
                  <em id="custom_display_1" class="milogo"></em>
                  <h4 class="header_tit_txt" id="login-title">
                    长乐未央帐号登录
                  </h4>
                </div>
              </div>
              <div class="tabs-con tabs_con now" data-con="pwd">
                <div>
                  <div class="login_area" id="login-main-form">
                    <div class="loginbox c_b">
                      <div
                        class="lgn_inputbg c_b login-panel pwdLogin sms_login"
                      >
                        <label
                          id="region-code"
                          class="labelbox login_user c_b disable add_regioncode"
                        >
                          <input
                            class="item_account"
                            autocomplete="off"
                            type="text"
                            v-model="user.username"
                            id="username"
                            placeholder="用户名"
                          />
                        </label>

                        <label class="labelbox pwd_panel c_b">
                          <input
                            class="item_account"
                            type="password"
                            placeholder="密码"
                            autocomplete="off"
                            id="pwd"
                            v-model="user.password"
                          />
                        </label>
                      </div>

                      <div class="btns_bg">
                        <input
                          class="btnadpt"
                          id="login-button"
                          type="button"
                          value="立即登录"
                          @click="handleSubmit"
                        />
                      </div>
                      <div class="other_panel clearfix">
                        <div class="reverse" id="extra-links">
                          <div
                            class="n_links_area reg_forget_links reg-forget-links"
                            id="custom_display_64"
                          >
                            <a class="outer-link" href=""
                              >还没有账号,现在注册</a
                            >
                          </div>
                        </div>
                        <div
                          class="other_login_type sns-login-container"
                          id="custom_display_16"
                        ></div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { fetchLogin } from "@/api/auth";

export default {
  data() {
    return {
      user: {
        username: "",
        password: "",
      },
    };
  },
  methods: {
    async handleSubmit() {
      let res;
      try {
        res = await fetchLogin(this.user);
        localStorage.token = res.data.token;
        this.$router.push({ name: "home" });
      } catch (err) {
        this.$toast.center(err.message);
      }
    },
  },
};
</script>

4、封装 axios 拦截器,验证 token

utils/request.js 中,全部代码:

import axios from "axios";

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000,
});

// request拦截器
service.interceptors.request.use(
  (config) => {
    // do something 在发送请求前
    const token = localStorage.token;
    if (token) {
      // 让每个请求携带token
      // ['X-Token']为自定义key
      // 请根据实际情况自行修改
      config.headers["token"] = token;
    }
    return config;
  },
  (error) => {
    // do something 当请求错误
    console.log(error); // for debug
    return Promise.reject(error);
  }
);

// response拦截器
service.interceptors.response.use(
  /**
   * 如果你想获取 http 信息,例如 headers 或 status
   * 请 return  response => response
   */

  /**
   * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
   * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
   */
  (response) => {
    const res = response.data;
    // console.log(111, res);
    // 如果返回的自定义code不是20000, 认定为error。
    if (res.code !== 20000) {
      // 单独判断除 20000 以外的响应码,返回 Promise 对象,不然页面会跳过这些响应码执行刷新
      if (res.code === 50001 || res.code === 50008 || res.code === 50014) {
        return Promise.reject(new Error(res.message || "Error"));
      }
      // 清除token
      localStorage.removeItem("token");

      // 跳转到登录页
      location.href = "/login";

      return Promise.reject(new Error(res.message || "Error"));
    } else {
      return res;
    }
  },
  (error) => {
    console.log("err" + error); // for debug
    return Promise.reject(error);
  }
);

export default service;

5、在 router/index.js 中,通过路由全局前置守卫和路由元信息设置访问权限。

.
.
{
    path: "/carts",
    name: "carts",
    component: () => import("../views/CartsView.vue"),
    meta: { requiresAuth: true },
},
.
.
// 路由导航守卫
router.beforeEach((to, from, next) => {
  if (to.matched.some((record) => record.meta.requiresAuth)) {
    const token = localStorage.token;
    if (token) {
      next(); // 执行下一步操作
    } else {
      next({
        path: "/login", // 跳转到登录页面
      });
    }
  } else {
    next(); // 确保一定要调用 next()
  }
});
.
.

例如这里通过 meta 给购物车设置元信息,代表购物车需要用户认证后才能访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值