配置Vite+React+TS项目

初始化

执行npm create vite并填写项目名、用那个框架。。

配置

路径别名

vite.config.ts里面配置:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, './src') // 路径别名
      ...
    }
  }
})

如果开发环境是ts,会提示如找不到path或找不到__dirname等,需要先安装一下node的类型声明文件:
npm i -D @types/node
或者
yarn add @types/node -D

然后去修改根目录的tsconfig.json文件,不然你使用路径别名引入组件的时候会报错,没写baseUrl vite会warning:

{
  "compilerOptions": {
    "baseUrl": "./",
    /* path alias */
    "paths": {
      "@/*": ["src/*"],
      ...
    }
  },
}

配置Less

直接执行npm i less就行
Vue3的话还需要下载一个less-loader插件

导入

关于在vue3导入组件的时候,默认是不能导入index.vue文件而不指定文件名,不然会报错:
在这里插入图片描述
需要在vite.config.js里面配置:

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": resolve(__dirname, './src')
    },
    extensions: ['.ts', '.js', '.vue', '.json'] // 这里
  }
})

ok,现在能运行了,但是编辑器还是报错了,很烦:
在这里插入图片描述
找一下项目根目录或者src目录有没有env.d.ts文件,如果没有,自己创建一个名字也随意,在里面写上

/// <reference types="vite/client" />
declare module '*.vue' {
    import { DefineComponent } from "vue"
    const component: DefineComponent<{}, {}, any>
    export default component
}

然后在tsconfig.ts里面配置:

"include": ["src/**/*.vue", "src/vite-env.d.ts"], // 我这里是在 src/vite-env.d.ts 写的,所以路径这样写

路由

react-router-dom是处理项目中路由问题的组件库,默认是没有这个组件库,需要额外下载:
npm add react-router-dom --save-dev
在根目录下的index.tsx里面把<App />外层包裹上:

import { BrowserRouter } from "react-router-dom";
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <BrowserRouter>
      <App />	
  </BrowserRouter>
);

自己去src里面创建router文件夹处理路由的信息,然后在App.tsx里面加上useRoutes:

import { Suspense } from 'react';
import { useRoutes } from 'react-router-dom'
import './App.css';
import routes from "./router"; // router文件夹的路由信息

function App() {
  return (
    <div className="App">
      <Suspense fallback="loading">
        <div className="main">
          {useRoutes(routes)}
        </div>
      </Suspense>
    </div>
  );
}

export default App;

封装Axios

import axios, { AxiosRequestConfig } from 'axios';

//默认请求超时时间
const timeout = 30000;

//创建axios实例
const service = axios.create({
  timeout,
  // 如需要携带cookie 该值需设为true
  withCredentials: true,
  // headers:{
  //   Authorization:"Basic YWRtaW46dGVzdA=="
  // }
});

// function getCookie(cookieName:any) {
//   const name = cookieName + "=";
//   const decodedCookie = decodeURIComponent(document.cookie);
//   const cookieArray = decodedCookie.split(';');
//   for (let i = 0; i < cookieArray.length; i++) {
//     let cookie = cookieArray[i];
//     while (cookie.charAt(0) === ' ') {
//       cookie = cookie.substring(1);
//     }
//     if (cookie.indexOf(name) === 0) {
//       return cookie.substring(name.length, cookie.length);
//     }
//   }
//   return "";
// }

// const yourCookieValue = getCookie("FLOWABLE_REMEMBER_ME");

// 统一请求拦截 可配置自定义headers 例如 language、token等
service.interceptors.request.use(
  (config: any) => {
    
    // if(config.url.includes("/workFlow")){
      
      
    //   config.headers.cookie = 'FLOWABLE_REMEMBER_ME' + yourCookieValue
    //   console.log(config.headers);
    // }
    return config
  },
  error => {
    console.log(error)
    Promise.reject(error)
  }
)

// axios返回格式
interface axiosTypes<T>{
  data: T;
  status: number;
  statusText: string;
}

// axios.create()

// 后台响应数据格式
// interface responseTypes<T>{
//   code: number,
//   msg: string,
//   result: T
// }

//核心处理代码 将返回一个promise 调用then将可获取响应的业务数据
const requestHandler = <T>(method: 'get' | 'post' | 'put' | 'delete' | 'patch', url: string, params: object = {}, config: AxiosRequestConfig = {}): Promise<T> => {
  //   let response: Promise<axiosTypes<responseTypes<T>>>;
  let response: Promise<axiosTypes<any>>;
  // if(url.includes('/flowable')) config = {
  //   headers:{
  //   'Cookie': 'FLOWABLE_REMEMBER_ME' + yourCookieValue
  // }}
  switch(method){
    case 'get':
      response = service.get(url, {params: { ...params }, ...config});
      break;
    case 'post':
      response = service.post(url, params, {...config});
      break;
    case 'put':
      response = service.put(url, {...params}, {...config});
      break;
    case 'delete':
      response = service.delete(url, {params: { ...params }, ...config});
      break
    case 'patch':
      response = service.patch(url, {...params}, {...config});
      break;
  }
  
  return new Promise<T>((resolve, reject) => {
    response.then(res => {
      // 业务代码 可根据需求自行处理
      const data = res.data;
      
      if(res.status !== 200 && res.status !== 304){
        
        // 特定状态码 处理特定的需求
        if(data.code == 401){
          console.log('登录异常,执行登出...');
        }
        const e: string = JSON.stringify(data);
        console.log(`请求错误:${e}`)
        reject(data);
      }else{
        // 数据请求正确 使用 resolve 将结果返回
        resolve(res.data);
      }
    }).catch(error => {
      const e: string = JSON.stringify(error);
      console.log(`网络错误:${e}`)
      reject(error);
    })
  })
}

// 使用 request 统一调用,包括封装的get、post、put、delete等方法
const request = {
  get: <T>(url: string, params?: object, config?: any) => requestHandler<T>('get', url, params, config),
  post: <T>(url: string, params?: object, config?: AxiosRequestConfig) => requestHandler<T>('post', url, params, config),
  put: <T>(url: string, params?: object, config?: AxiosRequestConfig) => requestHandler<T>('put', url, params, config),
  delete: <T>(url: string, params?: object, config?: AxiosRequestConfig) => requestHandler<T>('delete', url, params, config),
  patch: <T>(url: string, params?: object, config?: AxiosRequestConfig) => requestHandler<T>('patch', url, params, config),
};

// 导出至外层,方便统一使用
export { request };
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值