vite5+vue3+js+axios+mock环境搭建

151 阅读5分钟

1. 目录

├── public
│   └── vite.svg
├── src
│   ├── assets
│   │   └── logo.png
│   ├── api
│   │   ├── axios.js
│   │   ├── demo.js
│   │   └── index.js
│   ├── mock
│   │   └── index.js
│   ├── components
│   │   └── HelloWorld.vue
│   ├── main.js
│   ├── router
│   │   ├── index.js
│   ├── style.css
│   ├── vite.config.js
│   └── views
│       └── Home.vue
│   ├── App.vue
│   └── main.js
├── vite.config.js
├── index.html
├── jsconfig.json
├── package.json
├── pnpm-lock.json
├── postcss.config.js
├── .prettierrc
├── .env.development
├── .env.production
└── .env.test
├── .gitignore
├── README.md

2. 特别说明

项目中使用pnpm,如果是npm或yarn,自行替换,其他命令也一样

3. 使用vite初始化项目

1. 初始化项目
# 初始化vite 项目名称可以自定义,其中 . 表示在当前目录创建 依次选择vue - javascript
pnpm create vite
# 安装依赖
pnpm install
# 启动项目
pnpm run dev
2. 安装完成后,可以删掉多余的文件
# 替换logo,或加入其他静态文件
src/assets/*
# 组件
src/components/*
3. 自定义vite.config.js配置文件,比如

1. 配置参考链接

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve('./src') // 配置别名,可以配置多个,但在文件中如果想识别的话,还需要在根目录添加jsconfig.json文件
    }
  },
  base: './', // 打包路径
  server: {
    port: 3000, // 服务端口号
    open: true, // 服务启动时是否自动打开浏览器
    cors: true // 允许跨域
  }
})
4. 配置jsconfig.json文件,与tsconfig.json类似

配置参考链接

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
5. 配置环境变量文件
  1. 在根目录下创建.env.development文件
# 配置环境变量
VITE_APP_TITLE=vite-vue3-js
  1. 在根目录下创建.env.production文件
# 配置环境变量
VITE_APP_TITLE=vite-vue3-js
  1. 在根目录下创建.env.test文件
# 配置环境变量
VITE_APP_TITLE=vite-vue3-js
  1. 使用
import.meta.env.VITE_APP_TITLE

3.安装vue-router处理路由

1. 安装vue-router
# --save表示添加到dependencies中,--save-dev表示添加到devDependencies中
pnpm install vue-router --save
2. 配置router/index.js文件
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '@/views/Home.vue'
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  }
]
const router = createRouter({
  history: createWebHashHistory(), // 配置路由模式: hash模式
  routes
})  
export default router
3. 配置main.js文件
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App);
app.use(router)
app.mount('#app')
4. 配置App.vue文件
<template>
  <div id="app">
    <router-view />
  </div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
</script>
5. 配置home.vue文件
<template>
  <div>
    <h1>Home</h1>
  </div>
</template>
<script setup>
</script>
6. 关于更多路由配置,可以查看我另一篇关于vue-router的文章

4. 安装axios处理请求

篇幅原因,可以参考我另一篇关于axios的文章 axios的个人二次封装

1. 安装axios
pnpm install axios --save
2. 配置axios/index.js文件
import axios from 'axios';
import { userStore } from '@/store/modules/user';

const CODE_MESSAGE = {
  200: '服务器成功返回请求的数据。'
  // 其他状态码
};

class HttpAxios {
  instance; // axios实例

  method = 'post'; // 请求方式

  timeout = 300 * 1000; // 超时时间

  cancelTokenArr = []; // axios cancelToken 数组,方便处理取消请求

  clearFlag = true; // 是否在切换页面时清除请求

  constructor(config) {
    let instance = axios.create(config);

    // 设置请求拦截
    instance.interceptors.request.use(this._requestInterceptors, (error) => {
      return Promise.reject(error);
    });

    // 设置返回拦截
    instance.interceptors.response.use(this._responseInterceptors, this._checkResponseError);

    this.instance = instance;
  }

  /**
   * 请求拦截,处理header部分传值及是否显示loading
   * @param config
   */
  _requestInterceptors = (config) => {
    // 其他逻辑
    config.cancelToken = new axios.CancelToken((cancel) => {
      this.cancelTokenArr.push({ cancel });
    });
    return Object.assign({}, config);
  };

  /**
   * 返回拦截
   * @param response
   * @returns
   */
  _responseInterceptors = (response) => {
    // 其他逻辑
    const { response } = error;
    const { status, statusText, data } = response || {};
    return Promise.reject(error);
  };
  /**
   * 发送请求
   */
  sendRequest = (url, params, method = 'post', config) => {
    if (!this.instance) {
      return;
    }
    this.method = method;
    const _method = method.toLocaleLowerCase();
    if (_method === 'get') {
      params = {
        params: params
      };
      return this.instance.get(url, params);
    }
    if (_method === 'formdata') {
      let reqData = new FormData();
      for (let key in params) {
        reqData.append(key, params[key]);
      }
      return this.instance.post(url, reqData);
    }
    return this.instance.post(url, params);
  };

  /**
   * 清除axios 请求
   */
  async clearRequests() {
    if (this.cancelTokenArr.length === 0 || !this.clearFlag) {
      return;
    }
    this.cancelTokenArr.forEach((ele) => {
      ele.cancel();
    });
    this.cancelTokenArr = [];
  }
}

// 获取实例
export const getHttpAxiosInstance = () => {
  let instance = null;
  return () => {
    if (!instance) {
      instance = new HttpAxios({}); 
    }
    return instance;
  }
}
3. 配置api/index.js文件
import { getHttpAxiosInstance } from "@/api/axios";
import demo from "@/api/demo";

export let httpAxios = getHttpAxiosInstance()();

// 请求方法转换
function toMethod(options) {
  options.method = options.method || 'post';
  const { method = 'post', url, config } = options;
  return (param = {}) => {
    return httpAxios.sendRequest(url, param, method, config);
  }
}
export function generateApiMap(maps) {
  let methodMap = {};
  for(let key in maps) {
    methodMap[key] = toMethod(maps[key]);
  }
  return methodMap;
}

export default {
  // 取出所有可遍历属性赋值在新的对象上
  ...generateApiMap({
    ...demo
  })
}
4. 配置api/demo.js文件
export default {
    demo: {
        method: 'post',
        url: '/demo'
    }
}
5. 使用:优化home.vue文件
<script setup>
import HelloWorld from '@/components/HelloWorld.vue'
import api from '@/api';

const request = async () => {
  const res = await api.demo();
  console.log(res);
}

request();
</script>
6. 修改vite.config.js, 配置代理
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve('./src') // 配置别名,可以配置多个,但在文件中如果想识别的话,还需要在根目录添加jsconfig.json文件
    }
  }
  server: {
    port: 3000, // 服务端口号
    open: true, // 服务启动时是否自动打开浏览器
    cors: true, // 允许跨域
    proxy: {
      '/api': {
        target: 'http://localhost:8080', // 代理地址
        changeOrigin: true, // 是否跨域
        rewrite: (path) => path.replace(/^\/api/, '') // 重写路径
      }
    }
  }
})

5. 安装mockjs模拟请求

中文文档

1. 安装mockjs
pnpm install mockjs --save-dev
2. 配置mock/index.js文件
import Mock from "mockjs";

// 拦截 /demo 请求
Mock.mock("/demo", {
    code: 0,
    message: "success",
    data: {
        id: 1,
        name: "@cname",
        email: "@email",
    },
});
3. 修改main.js文件
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import '@/mock' // 引入mockjs
const app = createApp(App);
app.use(router)
app.mount('#app')

6. 安装postcss处理响应式

中文文档

1. 安装依赖
pnpm install postcss --save-dev
# 转换为rem时安装
pnpm install postcss-pxtorem --save-dev
# 转换为vw时安装, 会提示过时,可以安装 postcss-px-to-viewport-8-plugin,相应的插件前缀也替换
pnpm install postcss-px-to-viewport --save-dev
2. 安装autoprefixer添加浏览器前缀
pnpm install autoprefixer --save-dev
3. 根目录下配置postcss.config.js文件
  1. 转为rem
// postcss.config.js
export default {
  plugins: {
    autoprefixer: {
        overrideBrowserslist: ['Chrome > 40', 'Firefox > 31', 'IE 11']
    },
    'postcss-pxtorem': {
      rootValue: 16, // rem与px的转换比例,1rem=16px
      unitPrecision: 5, // 转换后的精度,即小数点位数
      propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
      exclude: /\/node_modules\//i,
    },
  },
}
  1. 转为vw
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375, // 设计稿宽度,例如设计稿为375px,则设置为375
      unitPrecision: 5,
      propList: ['*'],
      viewportUnit: 'vw',
      fontViewportUnit: 'vw',
      selectorBlackList: [],
      minPixelValue: 1,
      mediaQuery: true,
      replace: true,
      exclude: /\/node_modules\//i,
    },
  },
};
4. 配置vite.config.js文件覆盖postcss.config.js文件
···
css: {
  postcss: {
    plugins: [
      require('postcss-pxtorem')({
        'postcss-pxtorem': {
            rootValue: 16, // rem与px的转换比例,1rem=16px
            unitPrecision: 5, // 转换后的精度,即小数点位数
            propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
            exclude: /\/node_modules\//i,
        },
      }),
    ],
  },
}
···

7. 安装prettier处理代码格式化

配置参考

1. 安装prettier
pnpm install prettier --save-dev
2. 根目录下配置.prettierrc文件:自行转换格式
{
  printWidth: 120, // 每行的字符数
  tabWidth: 2, // 缩进的空格数
  useTabs: false, // 是否使用制表符进行缩进
  semi: true, // 是否在语句末尾添加分号
  singleQuote: true,  // 是否使用单引号
  jsxSingleQuote: false, // 是否在JSX中使用单引号
  trailingComma: 'es5', // 是否在对象或数组的末尾添加逗号
  bracketSpacing: true, // 是否在对象或数组的括号之间添加空格
  jsxBracketSameLine: false, // 是否在JSX的括号中换行
  arrowParens: 'always', // 是否在箭头函数的参数周围添加括号
  endOfLine: 'lf', // 换行符类型
  ignorePath: '.prettierignore', // 忽略文件的路径
}

8. 项目地址