美文网首页
用vite搭建一个vue3 + ts项目

用vite搭建一个vue3 + ts项目

作者: 天气不不错 | 来源:发表于2022-01-26 15:00 被阅读0次

    vite + ts 项目搭建

    创建项目

    // 1. 全局安装vite
    npm i vite -g
    // 2. 创建项目
    npm init vite@latest
    // 3. 输入项目名称,选择模板
    // 4. 按提示运行npm install , npm run dev
    
    image-20220106103432239.png

    看上面的截图,这里面没有vue+ts 所以后面要手动添加ts,如果有vue+ts直接选择就好。

    vite.config.js

    import { defineConfig } from 'vite'
    // import path from 'path'
    import vue from '@vitejs/plugin-vue'
    import vueJsx from '@vitejs/plugin-vue-jsx'
    import { resolve } from 'path'
    
    // https://vitejs.dev/config/
    export default defineConfig({
      server: {
        host: '0.0.0.0', //use `--host` to expose
        port: 8099,
        open: true
      },
      resolve: {
        alias: {
          "@": resolve(__dirname, 'src')
        },
      },
      plugins: [vue(), vueJsx()]
    })
    

    集成ts

    1. 安装ts

      npm i typescript -S

    2. 创建tsconfig.json 文件

      npx tsc --init

    3. 将main.js改成main.ts,index.html引入也改成mian.ts

    4. 在项目根目录创建shim.d.ts文件,文件内 写入以下文件,用于ts识别.vue文件

    declare module "*.vue" {
        import { Component } from "vue";
        const component: Compoent;
        export default component;
    }
    

    tsconfig.json

    {
      "compilerOptions": {
          "target": "es2016", 
          "jsx": "preserve",
          "module": "esnext",
          "moduleResolution": "node",
          "baseUrl": "./", 
          "paths": {
              "@/*": [
                "src/*"
              ]
           }, 
          "strict": true,
           "skipLibCheck": true
      }
    }
    

    集成router

    1. 安装

      npm install vue-router@4

    2. 创建router/index.ts文件

       import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
       import HelloWorld from '@/components/HelloWorld.vue'
       const routes: Array<RouteRecordRaw> = [
         {
           path: '/',
           name: 'home',
           component: HelloWorld
         }
       ]
       
       const router = createRouter({
         history: createWebHashHistory(),
         routes
       })
       export default router
       
    
    1. 在main.ts中导入使用

      import router from './router/index'

      app.use(router)

    如果以模块(module)的形式使用router

    1. 在router中创建module目录

    2. 在module中创建一个模块的router文件

      如:setting.ts

    import type { RouteRecordRaw } from 'vue-router';
    
    const routes: RouteRecordRaw[] = [
      {
        component: () => import('@/pages/Settting.vue'),
        path: '/setting',
        redirect: { name: 'authority' },
        children: [
          {
            path: 'authority',
            name: 'Authority',
            component: () => import('@/pages/settting/Authority.vue'),
          },
          {
            path: 'userList',
            name: 'UserList',
            component: () => import('@/pages/settting/UserList.vue'),
          },
        ],
      },
    ];
    
    export default routes;
    
    1. 在router目录下创建index.ts文件,并导入模块
      import type { RouteRecordRaw } from 'vue-router';
      import { createRouter, createWebHashHistory } from 'vue-router';
      // vite2
      const routes: RouteRecordRaw[] = [];
      
      const modules = import.meta.globEager('./module/*.ts');
      for (const path in modules) {
        routes.push(...modules[path].default);
      }
      
      const router = createRouter({
        history: createWebHashHistory(),
        routes: routes,
      });
      
      export default router;
    

    这段代码的意思是获取当前module文件夹下的所有ts结尾的文件自动导入

    const modules = import.meta.globEager('./module/*.ts');
    for (const path in modules) {
       routes.push(...modules[path].default);
    }
    

    相当于在webpack中的这段代码

    // 参数:1. 目录  2. 是否加载子目录  3. 加载的正则匹配
    const importFn = require.context('./module/', false, /\.ts$/)
    importFn.keys().forEach(key => {
        const rt = importFn(key).default
        routes.push(rt);
    })
    

    集成vuex

    1. 安装

    npm install vuex@next --save

    1. 创建store/index.ts文件
    // store.ts
    import { InjectionKey } from 'vue'
    import { createStore, useStore as baseUseStore, Store } from 'vuex'
    
    export interface State {
      count: number
    }
    
    export const key: InjectionKey<Store<State>> = Symbol()
    
    export const store = createStore<State>({
      state: {
        count: 0
      },
      mutations: {
        setCount(state: State, count: number) {
          state.count = count;
        }
      },
      getters: {
        getCount(state: State) {
          return state.count
        }
      }
    })
    
    // 定义自己的 `useStore` 组合式函数
    export function useStore() {
      return baseUseStore(key)
    }
    
    1. 在main.ts中导入

    import { store, key } from './store/index'

    app.use(store, key)

    推荐使用pinia,不再使用vuex

    使用sass

    1. 安装

    npm install -D sass

    1. 配置公共变量

    在vite.config.js文件中添加

    css:{
         preprocessorOptions: {
          scss: {
            additionalData: `@import "style/_style.scss";`
          }
        }
    } 
    

    集成Axios

    安装npm install axios

    创建request.ts

    import axios from 'axios';
    // 里面就是定义了一些常量  NO_PERMISSION=401 ;OK_CODE=200
    import { NO_PERMISSION, OK_CODE } from '@/app/keys';
    import router from '@/router';
    // 可以从其他文件导入的
    export interface UserInfo {
      id: number;
      username: string;
      role: string;
      email: string;
      token: string;
    }
    
    const requests = axios.create({
      baseURL: import.meta.env.VITE_API_URL,
      timeout: 10000,
    });
    
    //拦截器
    requests.interceptors.request.use((config) => {
      config = config || {};
      //pinia
      try {
        const user = JSON.parse(localStorage.getItem('user') || '') as UserInfo;
        if (user.token) {
          config.headers!['Authorization'] = `Bearer ${user.token}`;
        }
      } catch (e) {}
      return config;
    });
    
    requests.interceptors.response.use(
      (resp) => {
        const { code, msg } = resp.data || {};
        if (code !== OK_CODE) {
          return Promise.reject(msg);
        }
        if (code === NO_PERMISSION) {
          router.push({ name: 'Login' }).then();
          return Promise.reject(msg);
        }
        return Promise.resolve(resp);
      },
      (error) => {
        return Promise.reject(error);
      }
    );
    
    export default requests;
    

    这里有用到import.meta.env.VITE_API_URL,这是vite提供的用于区分开发和生产环境的

    在根目录创建.env.env.production分别表示开发时变量和生产时变量

    # .env
    VITE_API_URL=http://localhost:3031
    
    # .env.producttion
    VITE_API_URL=http://localhost:1212
    

    创建useHttp.ts

    import { Method } from 'axios';
    import requests from '@/api/requests';
    
    export interface HTTPConfig {
      url: string;
      method: Method;
      data?: { [key: string]: unknown };
      params?: { [key: string]: unknown };
    }
    const useHttp = <T>(config: HTTPConfig): Promise<T> => {
      return new Promise<T>((resolve, reject) => {
        requests({
          url: config.url,
          method: config.method,
          data: config.data || {},
          params: config.params || {},
        })
          .then((resp) => {
            resolve(resp.data);
          })
          .catch((err) => {
            reject(err);
          });
      });
    };
    
    export default useHttp;
    

    编写接口文件

    import useHttp from '@/api/useHttp';
    import { BasicResp } from '@/api/types';
    // BasicResp 是返回数据的外层通用的类型
    export interface BasicResp<T> {
      code: number;
      data: T;
      msg: string;
    }
    
    export interface RegParams {
      username: string;
      password: string;
      email: string;
    }
    export const reqUserRegister = (params: RegParams) => {
      //axios http
      return useHttp<BasicResp<null>>({
        url: `/v1/user`,
        method: 'post',
      });
    };
    
    export interface LoginParams {
      username: string;
      password: string;
    }
    
    export interface LoginData {
      info: UserInfo;
      token: string;
    }
    
    export const reqUserLogin = (params: LoginParams) => {
      //axios http
      return useHttp<BasicResp<LoginData>>({
        url: `/v1/user/login`,
        method: 'post',
        data: { ...params },
      });
    };
    

    相关文章

      网友评论

          本文标题:用vite搭建一个vue3 + ts项目

          本文链接:https://www.haomeiwen.com/subject/jnenhrtx.html