当前位置: 首页 > news >正文

vue3之写一个aichat ----vite.config.js

vite.config.js的CSS配置

在这里插入图片描述

postcss-pxtorem

开发响应式网页的时候需要用到postcss-pxtorem
amfe-flexible
amfe-flexible是由阿里团队开发的一个库,它可以根据设备的屏幕宽度去动态调整HTML根元素()的字体大小,这意味着无论用户使用什么尺寸的设备访问你的网站,页面都能根据设备的实际宽度进行缩放,从而达到响应式设计效果
工作原理:amfe-flexible会检测设备的屏幕宽度,并基于这个宽度设置一个基准字体大小,默认情况下,如果设备宽度为750px,则根字体被设置为100px,如果是375px宽,则根字体大小为50px,以此类推。
引入方式:在main.js中引入amfe-flexible
在这里插入图片描述

什么是postcss-pxtorem
postcss-pxtorem是PostCSS的一个插件,它的主要作用是将CSS中的px(像素)单位自动转换为rem(根em)单位,Rem单位基于HTML文档的根元素的字体大小来计算尺寸,这使得它可以很好的适应不同的屏幕尺寸和分辨率,从而帮助创建响应式设计
为什么选择Rem而不是px
灵活性:使用rem可以让你更容易地调整整个页面或者其他部分的缩放比列,只需要改变根元素的字体大小即可
响应式设计: rem单位非常适合用于响应式设计,因为它允许你根据用户的设备设置基础字体大小,并以此为基础进行相对缩放
postcss-pxtorem的使用
在这里插入图片描述
上面的 postcssPxToRem只能将标签内的css像素单位转换成rem,但是实际的项目开发中,我们需要用到行内样式,所以我们还需要写一个工具函数来转换行内样式的单位,在项目的src目录下创建 >utils文件夹 >创建pxToRem.js
pxToRem.js

const getBaseFontSize = () => {
// 使用 document.documentElement 获取 HTML 文档的根元素(即 <html> 标签)
  // getComputedStyle 是一个用于获取所有计算样式的接口,它返回一个包含所有计算样式的对象
  // .fontSize 属性从这个对象中获取根元素的字体大小属性值,该值是一个字符串,如 "16px"
  const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
  
  // parseFloat 函数将字符串转换为浮点数,这里是为了去掉 'px' 单位,只保留数字部分
  // 例如,如果 fontSize 返回的是 '16px',那么 parseFloat('16px') 将返回 16

  // 返回计算后的根字体大小,这是一个纯数字,表示当前页面根元素的字体大小(以像素为单位)
  return rootFontSize;
}

const pxToRem = px => {
  // 如果传入的是带单位的字符串(比如 '100px')
  if (typeof px === 'string') {
    // 如果包含 '%',直接返回
    if (/%/gi.test(px)) {
      return px;
    }
    // 去掉 'px' 单位
    px = parseFloat(px.replace('px', ''));
  }

  // 如果传入的不是数字,直接返回
  if (isNaN(px)) {
    return px;
  }

  // 使用 amfe-flexible 设置的根字体大小进行计算
  const baseFontSize = getBaseFontSize();
  const remValue = (px / baseFontSize).toFixed(6) + 'rem';

  return remValue;
}

// 导出函数
export default pxToRem;

使用pxToRem.js
在需要使用的组件中引入文件再使用
在这里插入图片描述
preprocessorOptions预处理器选项,配置了预处理器是less
javascriptEnabled: true允许在less文件中使用JavaScript表达式,动态计算颜色值或根据条件生成样式有用
additionalData: '@import “@/assets/styles/variables.less”;'在每个less文件的开头自动导入@/assets/styles/variables.less文件这样,就可以在任何less文件中使用variables.less中定义的变量
在这里插入图片描述

vite.config.js中的server配置

在这里插入图片描述

基础服务配置:
host: 指定服务器监听的IP地址。0.0.0.0表示允许所有网络接口(包括本地和外部)访问服务
port:指定服务器运行的端口号,项目启动后可以通过http://localhost:8888/chatai/Chat或者外部IP访问
代理配置 (proxy):

'/api': {
 target: 'https://thecatapi.com/',
 changeOrigin: true,
 ws: true,
 timeout: 300000
},

作用:将所有请求代理到https://thecatapi.com/
配置项:
target:代理的目标服务器URL
changeOrigin:修改请求头中的Host为目标URL的主机名(绕过某些服务器的反爬机制)
ws: 启用webSocket代理(用于实时通信)
timeout:设置代理请求超时时间
路径匹配规则
所有以/api开头的请求都会被代理到https://thecatapi.com
例如:/api/cats → https://thecatapi.com/cats(自动去除/api前缀)
允许访问的主机 (allowedHosts):

   allowedHosts: [
      '8eec-113-106-75-166.ngrok-free.app', // 添加你的ngrok URL
     // 如果需要,可以添加其他允许的主机
      'localhost', // 允许本地访问
      '127.0.0.1' // 允许本地访问
],

作用:定义合法的主机名列表,防止未经授权的主机访问开发服务器
常用于ngrok暴露本地服务到公网时,需要添加生成的域名,一般开发H5移动端,想要手机调试可以使用这个方法,关于ngrok的安装使用可以参考这篇文章

前端请求发起到代理转发的全流程

前端axios实例配置的baseURL为/api,发送请求到vite开发服务器的8888端口,vite的server.proxy配置检测到/api开头的请求,转发到目标服务器,修改请求头,处理路径重写,然后返回响应
在这里插入图片描述
封装的axios,其中baseURL: ‘/api’,表示每个请求都会自动加上"/api"前缀,如:request.get(‘/cats’)实际的请求地址是http://localhost:8888/api/cats

import axios from 'axios'
import { useUserStore } from '@/stores/user'

// 创建 axios 实例
const request = axios.create({
  baseURL:'/api',
  timeout: 100000,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json;charset=utf-8',
    Accept: 'text/event-stream'
  }
})

// 创建请求取消控制器Map
const pendingMap = new Map()

// 生成取消请求的key
const getPendingKey = config => {
  const { url, method, params, data } = config
  return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&')
}

// 添加请求到pendingMap
const addPending = config => {
  const pendingKey = getPendingKey(config)
  if (!pendingMap.has(pendingKey)) {
    const controller = new AbortController()
    config.signal = controller.signal
    pendingMap.set(pendingKey, controller)
  }
}

// 移除请求从pendingMap
const removePending = config => {
  const pendingKey = getPendingKey(config)
  if (pendingMap.has(pendingKey)) {
    const controller = pendingMap.get(pendingKey)
    controller.abort()
    pendingMap.delete(pendingKey)
  }
}

// 请求拦截器
request.interceptors.request.use(
  config => {
    // removePending(config)
    addPending(config)

    // 如果是流式请求
    if (config.isStream) {
      config.responseType = 'blob'
      config.timeout = 0 // 禁用超时
    }

    // 判断是否需要转换为FormData
    if (config.formData === true && config.data) {
      let formData = new FormData()
      for (let key in config.data) {
        if (Array.isArray(config.data[key])) {
          config.data[key].forEach(value => {
            formData.append(`${key}[]`, value)
          })
        } else {
          formData.append(key, config.data[key])
        }
      }
      config.data = formData
      config.headers['Content-Type'] = 'multipart/form-data'
    }

    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  response => {
    removePending(response.config)

    // 如果是流式响应,直接返回response
    if (response.config.isStream) {
      return response
    }
    if (response.data.code == 215) {
      const userStore = useUserStore()
      userStore.clearUserState() //清除用户状态
    }
    return response.data
  },
  error => {
    if (error.name === 'AbortError') {
      console.log('请求被取消')
      return Promise.reject(error)
    }
    handleHttpError(error)
    return Promise.reject(error)
  }
)


// 处理 HTTP 错误
const handleHttpError = error => {
  if (error.response) {
    switch (error.response.status) {
      case 404:
        console.error('请求的资源不存在')
        break
      case 500:
        console.error('服务器错误')
        break
      default:
        console.error('网络错误')
    }
  } else if (error.request) {
    console.error('请求超时')
  } else {
    console.error('请求错误')
  }
}

export default request

在项目中启动的VConsole,用于调试移动端网页

viteVConsole函数用于初始化和配置VConsole,接收一个配置对象作为参数
entry,配置VConsole的入口文件,path.resolve用于将相对路径转换为绝对路径,指定了入口文件为src/main.js
enabled,设置VConsole的启用状态
config,用于配置VConsole的各种参数,maxLogNumber设置日志的最大数量,当日志超过这个数量,旧的日志就会被自动清除;theme设置VConsole的主题为黑色
在这里插入图片描述
当然在这之前的先安装相应的依赖,vconsole不必说
vite-plugin-vconsole自动集成vconsole,通过插件就可以实现vconsole的自动注入,无需修改代码;可以根据不同的构建环境动态的启动或者禁用vconsole,使用vite插件系统更攘夷进行扩展和维护

npm install vconsole  --save
npm install vite-plugin-vconsole  --save-dev//专门用于开发环境的工具

相关文章:

  • 路由器安全研究|D- Link DIR-823G v1.02 B05 复现与利用思路
  • 从零搭建 Vue 3 + Element Plus 项目实战指南
  • WPF跨平台开发探讨:借助相关技术实现多平台应用
  • mysql学习-常用sql语句
  • 解决SpringCloud整合Nacos启动报java.lang.IllegalArgumentException: illegal dataId
  • 设计C语言的单片机接口
  • Springdoc 全部注解一文解释清楚
  • Python的Pytest测试框架(1)
  • 实验一:统计字符个数
  • 【QT】-toUtf8() 和 toBase64()的区别
  • mysql5.7主从部署(docker-compose版本)
  • 【责任链模式的多种实现方式及其应用】
  • Modbus协议
  • LeetCode[142] 环形链表 II
  • 【C++】memset和memcpy函数
  • 案例驱动的 IT 团队管理:创新与突破之路:第二章 团队组建:从人才画像到生态构建-2.2.2案例:某游戏公司“特种作战小组“模式
  • NAT及P2P通信
  • 本地部署deepseek-r1建立向量知识库和知识库检索实践【代码】
  • defineExpose函数
  • matlab R2024b下载教程及安装教程(附安装包)
  • 最近这75年,谁建造了上海?
  • 张译、惠英红分获第二十届中国电影华表奖优秀男、女演员奖
  • 报告:到2030年我国无人机产业将率先实现万亿规模
  • 演员孙俪:中年人没有脆弱的时间,学习胡曼黎不内耗
  • 人民论坛:是民生小事,也是融合大势
  • 上海车展的“老头乐”,又升级了