vite --- 构建vue3项目

262 阅读1分钟

使用 vite 创建项目

指令:npm init vite@latest

1. 安装router

指令:npm install vue-router@4
配置:
    // index.ts
    import { createRouter, createWebHashHistory } from 'vue-router'
    import { routes } from './router'

    export const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    // router.ts
    import { RouteRecordRaw } from 'vue-router'
    export const routes: RouteRecordRaw[] = [
      {
        path: '/',
        name: 'layout',
        component: () => import('../views/LayoutPage.vue')
      }
    ]

2. 安装pinia

指令:npm install pinia
    // store/index.ts 数据持久化
    import { toRaw } from "vue";
    import { createPinia, PiniaPluginContext } from "pinia";
    const pinia = createPinia();

    type Options = {
      key?: string;
    };

    const _piniaKey: string = "key";

    const setStorage = (key: string, value: any) => {
      localStorage.setItem(key, JSON.stringify(value));
    };

    const getStorage = (key: string) => {
      return localStorage.getItem(key)
        ? JSON.parse(localStorage.getItem(key) as string)
        : {};
    };

    const piniaPlugin = (options: Options) => {
      return (context: PiniaPluginContext) => {
        const { store } = context;

        // toRaw 把指定数据变成原始对象
        const data = getStorage(`${options?.key ?? _piniaKey}-${store.$id}`);

        store.$subscribe(() => {
          setStorage(
            `${options?.key ?? _piniaKey}-${store.$id}`,
                toRaw(store.$state)
          );
        });

        return {
          ...data,
        };
      };
    };

    pinia.use(
      piniaPlugin({
        key: "pinia",
      })
    );

    export { pinia };
    
   * 注意点
       结合全局路由守卫使用,否则只在第一次加载页面或刷新页面触发store.$subscribe()
       // 添加路由守卫,实现权限控制
        router.beforeEach((to) => {
          const store = userStore()
          if (to.name !== 'login' && to.name !== 'register' && store.user.token === ''){
            router.replace({name: 'login'})
            return false
          } else {
            return true
          }
        })
       

3. 安装scss

指令:npm install --save-dev sass

4. 安装JSX/tsx插件

指令:npm install @vitejs/plugin-vue-jsx -D

5. eslint配置

地址:https://www.jianshu.com/p/4b94540dd998

6. vite.config.ts配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import eslintPlugin from 'vite-plugin-eslint'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueJsx(),
    eslintPlugin({
      // include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']
      include: ['src/**/*.ts', 'src/**/*.d.ts', 'src/**/*.tsx', 'src/**/*.vue'],
    }),
  ],
  resolve: {
    alias: {
      '@': '/src',
    },
  },
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `
          @import '@/assets/scss/variables.scss';
          @import '@/assets/scss/mixins.scss';
        `,
      },
    },
  },
  server: {
    port: 3000,
    strictPort: true, // 设为true时若端口已被占用则会直接退出,而不是尝试下一个可用端口
    https: '',
    open: false,
    proxy: {
      '/api': {
        //以 ^ 开头,将会被解释为正则,如:'^/fallback/.*'
        target: 'http://jsonplaceholder.typicode.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
        configure: (proxy, options) => {
          // proxy 是 'http-proxy' 的实例
        },
      },
    },
  },
})

7. request.js工具封装

import axios from "axios";
import qs from "qs";

const request = (url, method = 'get', data = {}, config = {}) => {
  axios.defaults.baseURL = import.meta.env.VITE_APP_BASE_API; 
  data = qs.stringify(data, {indices: false}); // 将对象或者数组序列化成URL的格式
  let axiosConfig = {
    url,
    method: method.toLocaleLowerCase(),
    timeout: 60000,
    withCredentials: true, // 跨域请求时发送Cookie
  }
  if (['post'].includes(method.toLocaleLowerCase())) {
    axiosConfig['data'] = data
  }
  if (['get', 'put', 'delete'].includes(method.toLocaleLowerCase())) {
    axiosConfig['params'] = data
  }
  if (config instanceof Object) {
    for (let key in config) {
      axiosConfig[key] = config[key];
    }
  }
  return axios(axiosConfig).then(res => res.data)
}

// 添加请求拦截器
axios.interceptors.request.use(
  (res) => {
    // post请求时 参数放在body中。
    res.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
    // const store = userStore();
    // if (store.user.token) {
    //     res.headers.Authorization = `Bearer ${store.user.token}`;
    // }
    return res;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 添加响应拦截器
axios.interceptors.response.use(res => res, error => Promise.reject(error));

export default request;