美文网首页
vue3+vite+windicss+pinia+vue-rou

vue3+vite+windicss+pinia+vue-rou

作者: 辛未羊的前端随笔 | 来源:发表于2022-09-06 11:52 被阅读0次

    1、创建项目
    采用vite创建vue项目

    yarn create vite my-vue-app --template vue-ts
    

    2、添加路由

    yarn add vue-router@4
    

    在src下创建router文件夹
    添加文件config.ts 存放文件路由
    config.ts

    import { RouteRecordRaw } from 'vue-router'
    let layout = () => import('@/layout/index.vue')
    const routers:Array<RouteRecordRaw> = [
        {
            path: '/',
            name: 'index',
            component: layout,
            children:[
                {
                    path: '/',
                    name: 'Home',
                    component: () => import('@/views/home/home.vue'),
                },
                {
                    path: 'user',
                    name: 'user',
                    component: () => import('@/views/user/user.vue')
                },
            ]
        },
        {
            path: '/login',
            name: 'login',
            component: () => import('@/views/login/login.vue')
        },
      ]
      export default routers
    
    

    创建index.ts 文件 生成路由

    import { createRouter, createWebHistory } from 'vue-router'
    import routers from './config'
    const router = createRouter({
        history: createWebHistory(),
        routes: routers
    })
    // 路由拦截器
    router.beforeEach((to, from, next) => {
        // TODO: 自定义拦截内容
        console.log(to, from, next)
        next();
      });
      
    export default router
    

    在main.ts 下引用router

    import router from '@/router/index'
    createApp(App).use(router)
    

    这个时候会报错@找不到,这个我们随后会配置。这里可以暂时改成用../来引用
    3、添加pinia

    yarn add pinia
    

    src下创建store文件夹并添加文件index.ts 添加文件夹modules,modules下添加app.ts以及user.ts
    index.ts内容

    import { createPinia } from 'pinia'
    
    const store = createPinia()
    export { store }
    

    modules/app.ts

    import { defineStore } from 'pinia'
    interface stateType {
        msg:string,
        count:number
    }
    
    export const appStore = defineStore('app',{
        state: ():stateType=>{
            return {
                count: 0,
                msg: '15898970112'
            }
        },
        getters: {
            doubleNum:(state)=>{
                console.log(111111,appStore)
                return state.count * 2
            }
        },
        actions: {
            changeCount(){
                this.count ++
            }
        }
    })
    

    modules/user.ts

    import { defineStore } from 'pinia'
    
    interface userStateType{
        userName:string,
        tel:string|number,
        passWord:string|number,
        userInfo?:Object
    }
    
    export  const userStore = defineStore('user',{
        state: ():userStateType=>{
            return {
                userName:'张三',
                tel:'13838384388',
                passWord:'123456'
            }
        },
        getters: {
            tonken:(state)=>{
                console.log(state);
                return '123456789'
            }
        },
        actions:{
            getUser(){
                return {
                    userName:this.userName
                }
            }
        }
    })
    

    在main.ts中引用

    import { store } from '@/store/index'
    createApp(App).use(router).use(store)
    

    这个跟路由一样 可以先改成用../引用
    4、设置‘@’
    在tsconfig.json中添加

    "paths": {
          "@/*": [
            "src/*"
          ]
        },
    

    在vite.config.ts 下添加

    resolve:{
        alias: [
          {
            find: /\@\//,
            replacement: pathResolve('src') + '/',
          },
        ],
      },
    

    5、添加 Ant Design Vue

    yarn add ant-design-vue@next
    

    然后配置ant-design-vue按需加载

    yarn add unplugin-vue-components -D
    

    由于此插件无法处理非组件模块,如 message,这种组件需要手动加载在main.ts 下引用

    import { message } from 'ant-design-vue';
    import 'ant-design-vue/es/message/style/css';
    createApp(App).use(message)
    

    在vite.config.ts 下添加

    import Components from 'unplugin-vue-components/vite'
    import {
      AntDesignVueResolver,
    } from 'unplugin-vue-components/resolvers'
    export default defineConfig({
      plugins: [
        vue(),
        Components({
          resolvers: [
            AntDesignVueResolver(),
          ],
        })
      ],
    })
    

    6.添加Windi CSS
    这个插件我感觉很好用 可以少些很多样式代码

    yarn add vite-plugin-windicss windicss -D
    

    然后,在你的 Vite 配置中添加插件vite.config.ts

    import WindiCSS from 'vite-plugin-windicss'
    
    export default {
      plugins: [
        WindiCSS(),
      ],
    }
    

    最后,在你的 Vite 入口文件中导入 virtual:windi.css:
    main.ts

    import 'virtual:windi.css'
    

    7、配置axios
    src下添加utils/http/index.ts utils/http/requests.ts
    index.ts

    import Axios from 'axios';
    const baseURL = '';
    const axios = Axios.create({
      baseURL, // 基础 url
      timeout: 10000 // 超时 10s
    });
    
    // 请求拦截器
    axios.interceptors.request.use(
      config => {
        // TODO: 配置请求内容
    
        // config.headers.Authorization = `Bearer ${token}`;
        return config;
      },
      error => {
        return Promise.reject(error);
      }
    );
    
    // 响应拦截器
    axios.interceptors.response.use(
      response => {
        // TODO: 配置对响应内容的处理
    
        return response;
      },
      error => {
        let { response } = error;
        if (error && error.response) {
          switch (error.response.status) {
            case 400:
              response.message = '未知错误';
              break;
            case 401:
              response.message = '未授权';
              break;
            case 403:
              response.message = '权限不足';
              break;
            case 404:
              response.message = '数据不存在';
              break;
            case 405:
              response.message = '不允许的请求方法';
              break;
            case 408:
              response.message = '请求超时';
              break;
            case 415:
              response.message = '不支持的媒体类型';
              break;
            case 500:
              response.message = '服务器出现异常';
              break;
            case 501:
              response.message = '网络未实现';
              break;
            case 502:
              response.message = '网络错误';
              break;
            case 503:
              response.message = '服务不可用';
              break;
            case 504:
              response.message = '网络超时';
              break;
            case 505:
              response.message = 'http版本不支持该请求';
              break;
            default:
              response.message = `其他错误。错误代码:${error.response.status}`;
          }
        } else {
          response = { message: '无法连接到服务器!' };
        }
        return Promise.reject(response);
      }
    );
    
    export default axios;
    
    

    requests.ts

    import axios from './index';
    
    /**
     * @param  promise
     * @param errorExt - Additional Information you can pass to the err object
     */
    function to<T, U = unknown>(
      promise: Promise<T>,
      errorExt?: object
    ): Promise<[U | null, T | undefined]> {
      return promise
        .then<[null, T]>((data: T) => [null, data])
        .catch<[U, undefined]>(err => {
          if (errorExt) {
            Object.assign(err, errorExt);
          }
    
          return [err, undefined];
        });
    }
    
    /**
     * GET methods
     * @param url
     * @param data
     * @returns {Promise}
     */
    export function get<T>(url: string, params = {}): TO<T> {
      return to(
        new Promise((resolve, reject) => {
          axios
            .get(url, {
              params
            })
            .then(result => {
              resolve(result.data as T);
            })
            .catch(err => {
              reject(err);
            });
        })
      );
    }
    
    /**
     * POST methods
     * @param url
     * @param data
     * @returns {Promise}
     */
    export function post<T>(url: string, data?: Record<string, unknown>): TO<T> {
      return to(
        new Promise((resolve, reject) => {
          axios
            .post(url, data)
            .then(result => {
              resolve(result.data as T);
            })
            .catch(err => {
              reject(err);
            });
        })
      );
    }
    
    /**
     * PUT methods
     * @param url
     * @param data
     * @returns {Promise}
     */
    export function put<T>(url: string, data?: Record<string, unknown>): TO<T> {
      return to(
        new Promise((resolve, reject) => {
          axios
            .put(url, data)
            .then(result => {
              resolve(result.data as T);
            })
            .catch(err => {
              reject(err);
            });
        })
      );
    }
    
    /**
     * DELETE methods
     * @param url
     * @param data
     * @returns {Promise}
     */
    export function del<T>(url: string, data?: Record<string, unknown>): TO<T> {
      return to(
        new Promise((resolve, reject) => {
          axios
            .delete(url, data)
            .then(result => {
              resolve(result.data as T);
            })
            .catch(err => {
              reject(err);
            });
        })
      );
    }
    
    

    下面附上完整的tsconfig.json文件以及vite.config.ts
    tsconfig.json

    {
      "compilerOptions": {
        // 允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。
        "allowSyntheticDefaultImports": true,
    
        // 解析非相对模块名的基准目录
        "baseUrl": ".",
    
        "esModuleInterop": true,
    
        // 从 tslib 导入辅助工具函数(比如 __extends, __rest等)
        "importHelpers": true,
    
        // 指定生成哪个模块系统代码
        "module": "esnext",
    
        // 决定如何处理模块。
        "moduleResolution": "node",
    
        // 启用所有严格类型检查选项。
        // 启用 --strict相当于启用 --noImplicitAny, --noImplicitThis, --alwaysStrict,
        // --strictNullChecks和 --strictFunctionTypes和--strictPropertyInitialization。
        "strict": true,
    
        // 生成相应的 .map文件。
        "sourceMap": true,
    
        // 忽略所有的声明文件( *.d.ts)的类型检查。
        "skipLibCheck": true,
    
        // 指定ECMAScript目标版本
        "target": "esnext",
    
        // 要包含的类型声明文件名列表
        "types": [
    
        ],
        "jsx": "preserve",
        "isolatedModules": true,
    
        // 模块名到基于 baseUrl的路径映射的列表。
        "paths": {
          "@/*": [
            "src/*"
          ]
        },
        // 编译过程中需要引入的库文件的列表。
        "lib": [
          "ESNext",
          "DOM",
          "DOM.Iterable",
          "ScriptHost"
        ]
      },
      "include": [
        "src/**/*.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "tests/**/*.ts",
        "tests/**/*.tsx"
      ],
      "references": [{ "path": "./tsconfig.node.json" }],
      "exclude": [
        "node_modules"
      ]
    }
    
    

    vite.config.ts

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import { resolve } from 'path'
    import WindiCSS from "vite-plugin-windicss"; 
    import Components from 'unplugin-vue-components/vite'
    import {
      AntDesignVueResolver,
    } from 'unplugin-vue-components/resolvers'
    function pathResolve(dir: string) {
      return resolve(process.cwd(), '.', dir);
    }
    export default defineConfig({
      plugins: [
        vue(),
        WindiCSS(),
        Components({
          resolvers: [
            AntDesignVueResolver(),
          ],
        })
      ],
      build: {
        // 去除console
        terserOptions: {
          compress: {
            drop_console: true,
            drop_debugger: true
          }
        }
      },
      resolve:{
        alias: [
          {
            find: /\@\//,
            replacement: pathResolve('src') + '/',
          },
        ],
      },
      base: './', // 设置打包路径
      server: {
        port: 3030, // 设置服务启动端口号
        open: true, // 设置服务启动时是否自动打开浏览器
        cors: true // 允许跨域
        // 设置代理,根据我们项目实际情况配置
        // proxy: {
        //   '/api': {
        //     target: 'http://xxx.xxx.xxx.xxx:8000',
        //     changeOrigin: true,
        //     secure: false,
        //     rewrite: (path) => path.replace('/api/', '/')
        //   }
        // }
      }
    })
    

    这样就可以用@符号代替src了

    完成项目地址:https://github.com/long3268671/vue3-vite-ts-demo

    相关文章

      网友评论

          本文标题:vue3+vite+windicss+pinia+vue-rou

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