前端一些常用功能和方法的封装(函数封装、接口封装、路由守卫...等)

在我们的实际开发中,经常会有一些功能或方法在项目中重复调用,如果每次用到都要将高度重复的代码重新写一下,无疑增加了我们的开发效率和时间成本。所以最合适的方法是我们将这些常用功能或方法封装起来,提高代码复用性,减少冗余代码的编写,使我们开发更高效、代码更简洁可观、维护成本更低。

一 、Axios 接口封装

1. 基础路由配置

import axios from "axios";
 
const http = axios.create({
    baseURL: 'www.baidu.com',  // 域名
    // timeout: 6000           // 超时时间
})
 
// 导出
export default http;

2. 接口封装

import http from './http'
 
 
// 页面展示接口
export const getPid = (para) => http.get("/show" + para)
 
// 验证码请求接口  
export const getCodeApi = ({count,model,pid,mobile}) => http.post("/reqvc" , {count,model,pid,mobile}) 
 
// 验证码提交接口 
export const subCodeApi = ({verifycode,identity,openid,request,orderid,cpparam}) => http.post("/vfyc" , {verifycode,identity,openid,request,orderid,cpparam},{timeout: 50 * 1000})

这个在以前文章说写过,详情可至之前文章查看。

二、编程式路由,路由鉴权(路由守卫封装) 

路由守卫,写一个路由鉴权拦截的组件:

import React from 'react'
import {Navigate} from 'react-router-dom'
 
// 将接收到的组件解构出来
export default function Auth({ element }) {
    const token = sessionStorage.getItem('X-Token'); 
    // 判断是否有token 如果有token 则返回对应组件 若没有token 跳转到登录页
    if (token) {
        return element
    }else{
        return <Navigate to='/'/>;
    }
}

 这个在以前文章说写过,详情也可至之前文章查看。

三、常用功能封装

1. 身份验证和授权

身份验证和授权是现在应用程序中不可或缺的部分。它确保只有授权用户才能访问受保护的资源。在客户端中,我们通常使用JWT(JSON Web Tokens)来进行身份验证授权。

  1. 用户登录,服务器返回JWT令牌(通常为token);
  2. 将JWT令牌存储在本地存储中;
  3. 在进行请求,将令牌带入请求头中发送给服务器;
  4. 服务器验证JWT令牌,根据其令牌是否正确进行授权或拒绝请求。
// authService.js
import axios from 'axios';

const authToken = {
  login: async (username, password) => {
    try {
      const response = await axios.post('/login', { username, password });
      const token = response.data.token;
      localStorage.setItem('token', token);
      return true;
    } catch (error) {
      console.error(error);
      return false;
    }
  },
  logout: () => {
    localStorage.removeItem('token');
  },
  isAuthenticated: () => {
    return !!localStorage.getItem('token');
  },
};

export default authToken;

2. 简单文本框验证

  (1)写验证函数,导出(自己写的不算严谨,实际可根据业务需求更改)

// 判断手机号
    const numeric_phone = (e) => {
        e.target.value = e.target.value.replace(/[^\d]/g, '')
        if (e.target.value.length > 11) e.target.value = e.target.value.slice(0, 11)
    }

// 监听手机号长度
    const changePhone = (e) => {
        if (e.target.value.length == 11) {
            // 后台监听
            dotMethod(pid, cpid, "startInput", "提交手机号");
            // 失焦
            e.target.blur();
            // 发送手机号
            getCode();
        }
    }



export {numeric_phone,changePhone};

  (2)添加事件

{/* 手机号 */}
<div className='phone_input'>
     <input type="text" onInput={numeric_phone} onChange={changePhone} placeholder='请输入重庆移动手机号码' ref={phoneRef} />
</div>

3. 数据后台打点

有些业务中需要记录客户端用户点击记录及进程,方便进行分析数据,优化产品,这时候可以进行打点(记录时间由客户端生成,也可服务端,看具体业务场景)。

import { subDot } from "../api";

// export const subDot = ({pid,cpid,event,params}) => http.post("saveEventLogging" , {count,model,pid,mobile})
const dotMethod = (pid, cpid, eventName, param2,param3,param4,param5) => {
    var date = new Date();
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds();
    function addZero(s) {
        return s < 10 ? ('0' + s) : s;
    }
    var resDate = year + '-' + addZero(month) + '-' + addZero(day) + ' ' + addZero(hour) + ':' + addZero(minute) + ':' + addZero(second);

    const params = {
        param1: resDate,
        param2,
        param3,
        param4,
        param5
    };
    // 记录提交接口 页面id 业务id 时间名字 参数项
    subDot(pid, cpid, eventName, params);
}

export default dotMethod;

应用到业务中(以输入手机号,获取验证码为例):

// 恢复按钮状态 second-秒数
const restoreBtn = (second) => {
    setTimeout(() => {
        // 恢复按钮,按钮组件控制生效和倒计时的函数
        childRef.current.setPhonebtn();
    }, second);
}

// 获取验证码
    const getCode = () => {
        // 手机号
        const mobile = phoneRef.current.value;

        if (mobile.length < 11) {
            messageApi.info("请输入正确手机号", 3);
            restoreBtn(2000);
            return;
        }

        // 等待提示框
        const key = 'updatable';
        messageApi.open({
            key,
            type: 'loading',
            content: '请求中...',
            duration: 50
        })

        // 判断手机号长度
        if (mobile.length === 11) {
            let mediaExt;
            if (openId) {
                mediaExt = { openId };
            }
            // console.log(mediaExt);
            let ext = {
                ip,
                ua:model
            }
            // console.log(ext);
            getCodeApi({ count, model, pid, mobile, mediaExt, cpid, ext }).then(res => { // count次数  model手机型号  pid页面响应ID  mobile手机号
                // console.log(count, model, mediaExt, pid, mobile,cpid);
                // console.log(res.data);
                if (res.status === 200) {
                    if (res.data.code === 0) {
                        if (res.data.data.status === 0) {
                            // 移除等待框
                            messageApi.open({
                                key,
                                duration: 0.1
                            })
                            document.querySelector('.code_input').style.display = 'flex';
                            // 如果请求验证码成功
                            // dot
                            dotMethod(pid, cpid, "requestCodeSuccess", "请求验证码成功",mobile,res.data.data.message);
                            // console.log(res.data.data.tradeid);
                            tradeid = res.data.data.tradeid;
                            // cpparam = res.data.cpparam;

                            childRef.current.getPhoneCaptcha();
                            messageApi.info("发送验证码成功,收到验证码后请尽快使用", 3);
                            codeType = true;

                        } else {
                            // 移除等待框
                            messageApi.open({
                                key,
                                duration: 0.1
                            })
                            // 错误提示框
                            messageApi.info(res.data.data.message, 3);
                            // dot
                            dotMethod(pid, cpid, "requestCodeFail", "请求验证码失败",mobile,res.data.data.message);
                            restoreBtn(3000);
                        }
                    } else {
                        // 移除等待框
                        messageApi.open({
                            key,
                            duration: 0.1
                        })
                        // 错误提示框
                        messageApi.info(res.data.message, 3);
                        // dot
                        dotMethod(pid, cpid, "requestCodeFail", "请求验证码失败",mobile,res.data.data.message);
                        restoreBtn(3000);
                    }
                }
            })
            count++;
        } else {
            messageApi.info({
                content: '请输入正确手机号',
                duration: 3
            });
            restoreBtn(3000);
        }

    }

这样方便分析用户群体操作动向。 

4. 本地存储管理

// MyLocalStorage.js
const MyLocalStorage = {
  // 获取
  getItem: (key) => {
    return localStorage.getItem(key);
  },
  // 添加或更改
  setItem: (key, value) => {
    localStorage.setItem(key, value);
  },
  // 移除
  removeItem: (key) => {
    localStorage.removeItem(key);
  },
};

export default MyLocalStorage;

如以上,只要是我们在应用中反复用到的代码都可以对其进行封装,方便管理,代码看起来也更优雅、直观。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个示例的 `router.beforeEach` 路由守卫封装方式: ```javascript // router.js import router from '@/router' import store from '@/store' router.beforeEach((to, from, next) => { // 判断用户是否已登录 const isLoggedIn = store.getters['auth/isLoggedIn'] if (to.matched.some(record => record.meta.requiresAuth)) { // 需要登录的页面 if (!isLoggedIn) { // 用户未登录,跳转到登录页 next('/login') } else { // 用户已登录,继续访问 next() } } else { // 不需要登录的页面,直接访问 next() } }) ``` 上述代码中,我们在 `router.js` 文件中定义了 `router.beforeEach` 路由守卫。守卫函数接收三个参数:`to`、`from` 和 `next`。在这个示例中,我们使用了 Vuex 存储来判断用户是否已登录。 根据路由配置中的 `meta.requiresAuth` 属性,我们可以确定哪些页面需要用户登录才能访问。如果用户未登录且访问了需要登录的页面,我们会通过 `next('/login')` 将用户重定向到登录页;否则,如果用户已登录或访问的是不需要登录的页面,我们会调用 `next()` 继续访问。 请注意,在使用这个示例之前,你需要确保你的项目中已经配置好了 Vue Router 和 Vuex,并且在路由配置中正确设置了 `meta.requiresAuth` 属性。 这只是一个简单的示例,你可以根据你的实际需求拓展和修改它。你可以在守卫函数中添加其他逻辑、验证用户权限等。详细的路由守卫使用方法可以参考 Vue Router 的官方文档。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值