大事件vue项目前端知识小总结

目录

同步的等待服务器响应的结果:

拦截器

跨域问题

Vue项目中pinia的使用(类似于Springboot中的ThreadLocal)

参数传递问题


笔记总结:

在我们从前端通过axios发送异步请求,就会等待服务器给我们响应结果,因为这是一个异步的,所以服务器响应的这个结果什么时候返回来我们就不得知了(它需要耗费时间)。

同步的等待服务器响应的结果:

我们可以借助于js提供的await(同步的等待服务器响应结果,如果服务器没有响应回来,这个方法就不会结束)和aysnc(把函数设置成异步函数)

例如:

const addCategory = async() =>{
    //调用接口
    let result = await articleCategoryAddService(categoryModel.value);
    ElMessage.success(result.message? result.message:'新增成功');

    //新增成功了应该刷新一下页面 , 调用获取所有文章分类的函数
    articleCategoryList();
    dialogVisible.value = false;
}

拦截器

背景:在我们写每次发送完请求后,都有then和catch且这些代码都是重复性代码,我们可以进行优化

3420fe72dc0a42a8a660ca1e050bf242.png

封装到一个工具类request.js中

560e97b8313e45758c585b06b466d061.png

(Promise.reject(err)的作用就是:把异步的状态转换成失败的状态)

实例:

//添加响应拦截器
instance.interceptors.response.use(
    result=>{
        if(result.data.code === 0)
        return result.data;

        // alert(result.data.msg?result.data.msg:'服务异常');
        ElMessage.error(result.data.msg?result.data.msg:'登陆失败');
        return Promise.reject(result.data);
    },
    err=>{
            //如果响应状态码时401,代表未登录,给出对应的提示,并跳转到登录页
        if(err.response.status === 401){
            ElMessage.error('请先登录');
            router.push('/login');
        }
        else {
            ElMessage.error('服务异常');
        }
        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;

(我们添加的拦截器本身就是异步的,所以我们在调用的js代码中不需要写await和aysnc)

跨域问题

f42af59029a141cdab4219f81c1d3c5c.png

比如我们在前端页面进行后端服务(前端的端口是5173,后端的端口是8080)

9ec2fcd800774d1d831a40deaf8993fc.png

解决方法:通过配置代理的方式

只有浏览器才有跨域问题,如果我们从服务端发起,就不会有跨域问题

2f48e2fd0fca48bb9af094d680328a24.png

实现:

首先在request.js中

a7e090a249be4845a649285bd0ebbbf4.png

原来的baseURL:'http://localhost:8080'改成'/api',/api的作用是给我们访问后台的路径添加一个标识,如果我们没有配置localhost:8080什么的,它会默认把AJAX请求所在的圆给他拼上去(http://localhost:5173/api)

还需要在vite.config.js中进行配置

e56cd03b312a4960bb5fa46470dc5d9a.png

实例:


import path from 'node:path'
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'


export default defineConfig({
  plugins: [
    vue(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  //配置代理
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080', // 后端服务器地址
        changeOrigin: true, // 是否改变请求域名
        rewrite: (path) => path.replace(/^\/api/, '')//将原有请求路径中的api替换为''
      }
    }
  }
})

具体实现

8637bf24984c453786b266271cf96df9.png

当我们发起这个请求后,我们在路径中发现了api,就会把路径换成http://localhost:8080,然后在配置代理中把api替换成' '

d7839d63198949ffbb0ddae89a68efa3.png

Vue项目中pinia的使用(类似于ThreadLocal)

使用场景:携带token

2ffea95162a1445a81d0cfffb719dbe5.png

使用方法:d6bda912a5004697bcaa0503e005b405.png

这样我们在登录成功后就可以把token存储到pinia中,实例:

//定义数据模型
const registerData = ref({
    username: '',
    password: '',
    rePassword: ''
})

import { ElMessage } from 'element-plus'
import {userRegisterService,userLoginService} from '../api/user.js'

//登录 绑定数据,复用注册表单的数据模型
//表单数据校验
//登录函数
//导入token状态
import { useTokenStore } from '@/stores/token.js'
import {useRouter} from 'vue-router'
const router = useRouter()
const tokenStore = useTokenStore();
const login = async() =>{
    //调用接口完成登录

    let result = await userLoginService(registerData.value)
    //把得到的token存储到pinia中
    tokenStore.setToken(result.data)

    ElMessage.success(result.message?result.message:'登录成功');
    //跳转到首页(借助于路由)
    router.push('/')
}

使用token:

import request from '@/utils/request'
import { useTokenStore } from '../stores/token'
//文章分类列表查询
export const articleCategoryListService = () => {
    //获取token状态
    const tokenStore = useTokenStore()
    //通过请求头Authorization携带token(已经在拦截器中做了统一处理)
    //在pinia中定义的响应式数据都不需要.value
    return request.get('/category', { headers: { 'Authorization': tokenStore.token } })
    // return request.get('/category')
}

但是如果我们每次在发送请求的时候都手动去写headers就会比较繁琐,为了解决这个问题,我们可以把获取token写到拦截器里面(请求拦截器)

import axios from 'axios';

import { ElMessage } from 'element-plus'
//定义一个变量,记录公共的前缀  
const baseURL = '/api';
//创建一个请求实例{通过传递一个js对象}
const instance = axios.create({baseURL})

//导入token状态
import { useTokenStore } from '@/stores/token.js';
import router from '../router';
//添加请求拦截器
instance.interceptors.request.use(
    (config)=>{
        //在发送请求之前做什么
        let tokenStore = useTokenStore()
        //如果token中有值,在携带
        if(tokenStore.token){
            config.headers.Authorization=tokenStore.token
        }
        return config
    },
    (err)=>{
        //如果请求错误做什么
        Promise.reject(err)
    }
)

我们需要为pinia添加一个持久化插件

abcaa02802bc4bb9b4cca01381179cf5.png

4a318e55bdd94bc09590e4506daf190c.png

参数传递问题

默认的传递参数类型是json类型的

如果参数是一个queryString类型的,我们可以拼在后面

export const articleDeleteService = (id)=>{

    //参数是一个queryString类型的
    return request.delete('/article?id='+id);

}

如果参数是x-www-form-urlencoded类型的(借助UrlSearchParams完成参数传递

export const userLoginService = (loginData) => {
    const params = new URLSearchParams();
    for(let key in loginData){
        params.append(key,loginData[key]);
    }
    return request.post('/user/login',params);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值