8000 GitHub - CDTRSFE/vite-tpl: ✨ Vite + Vue3 + TS template
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

CDTRSFE/vite-tpl

Repository files navigation

Vite 项目模版

特性

使用

npx degit CDTRSFE/vite-tpl my-project
cd my-project
git init
pnpm i
pnpm dev

目录

.
├── .husky
│   ├── commit-msg                   # commit message 格式检测
│   └── pre-commit                   # git 钩子,commit 之前执行 pnpm lint, pnpm styelint
├── .vscode
├── public                           # 静态资源文件夹
│   └── favicon.ico
├── src
│   ├── App.vue                      # 根组件
│   ├── assets
│   │   ├── fonts                    # 字体文件夹
│   │   ├── icons                    # 图标文件夹
│   │   ├── images                   # 图片文件夹
│   │   └── styles                   # 样式文件夹
│   │       └── main.less            # 全局样式
│   ├── components                   # 全局组件文件夹
│   ├── directives                   # 全局指令文件夹
│   │   └── Focus.js
│   │   └── index.ts                 # 注册指令
│   ├── main.ts                      # 入口文件
│   ├── plugins
│   │   ├── axios.ts                 # axios
│   │   └── loading.ts
│   ├── router
│   │   └── index.ts                 # 路由
│   ├── store                        # 状态管理
│   ├── types
│   │   ├── auto-imports.d.ts        # 自动引入 API 的类型声明
│   │   ├── components.d.ts          # 自动注册组件的类型声明
│   │   ├── global.d.ts              # 全局类型声明
│   │   └── shims.d.ts               # 模块类型声明
│   └── views
│       └── Index.vue
├── .eslintrc-auto-import.json       # 自动引入的 API 全局变量配置
├── .gitignore
├── .prettierrc                      # prettier 配置
├── eslint.config.js                 # eslint 配置
├── index.html
├── README.md
├── commitlint.config.js             # commitlint 配置
├── stylelint.config.js              # stylelint 配置
├── uno.config.ts                    # unocss 配置
├── package.json
├── pnpm-lock.yaml
├── tsconfig.json                    # ts 配置
└── vite.config.ts                   # vite 配置

node 版本

推荐使用 Node.js v20.9.0 及以上版本。

🚀 axios

项目中引入了 axios,拦截器等相关配置在 src/plugins/axios.ts 中,axios 实例可作为全局变量直接访问,也可通过 Vue 组件的全局属性访问。

<script lang="ts">
export default defineComponent({
    created() {
        this.$axios('/xxx');
    },
});
</script>
<script lang="ts" setup>
window.axios.get('/xxx');
axios.get('/xxx');
</script>

通常情况下,发请求需要显示 loading 动画,所有请求都响应后关闭动画,可在 src/plugins/loading.ts 中修改具体的 loading 逻辑。对于不需要 loading 动画的请求可以在配置中添加 loading 属性:

axios.get('/xxx', { loading: false });

🚀 组件自动化加载

使用 unplugin-vue-components 自动按需引入组件,也无需注册,使用全局组件和 UI 组件库时更加方便。配置后,项目中放在 'src/components' 目录下的组件可在全局直接使用。

⚙️ 配置

// vite.config.ts

import { defineConfig } from 'vite';
import Components from 'unplugin-vue-components/vite';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';

export default defineConfig({
    plugins: [
        Components({
            dirs: ['src/components'],
            extensions: ['vue', 'js', 'ts'],
            include: [/\.vue$/, /\.vue\?vue/],
            dts: 'src/types/components.d.ts',
            resolvers: [
                AntDesignVueResolver(),
            ]
        }),
    ],
})
  • dirs 指定查找组件的相对路径,此目录下的组件并非全局注册。
  • dts: 'src/types/components.d.ts' 表示生成全局类型声明文件,用于 volar 类型提示。
  • AntDesignVueResolver 用于解析 ant-design-vue 组件引入。

🧐 使用

./src
├── components
│   ├── FullLoading.vue
│   └── TabSelect.vue
<template>
    <full-loading></full-loading>
    <a-button type="primary">btn<a/-button>
</template>

通过插件处理后,相当于:

<template>
    <full-loading></full-loading>
    <a-button type="primary">btn</a-button>
</template>

<script setup lang="ts">
import FullLoading from '@/components/FullLoading.vue';
import ElButton from 'ant-design-vue/es/button';
import 'ant-design-vue/es/button/style/css';
</script>

🚀 API 自动引入

通过 unplugin-auto-import 插件自动按需引入所需 API,ref, watch, useRouter 等 API 无需引入可直接使用。

<template>
    <div>{{ name }}</div>
</template>

<script setup lang="ts">
const name = ref('name');
</script>

⚙️ 配置

// vite.config.ts

import { defineConfig } from 'vite';
import AutoImport from 'unplugin-auto-import/vite';

export default defineConfig({
    plugins: [
        AutoImport({
            include: [/\.[tj]sx?$/, /\.vue$/, /\.vue\?vue/],
            imports: [
                'vue',
                'vue-router',
                '@vueuse/core',
            ],
            dts: 'src/types/auto-imports.d.ts',
            eslintrc: {
                enabled: true, // Default `false`
                filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
                globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
            },
        }),
    ],
});
  • include 指定需要转换的目标文件,自动引入 API 可以在 js, ts, jsx, tsx, vue 文件中使用。
  • imports 添加了 vue, vue-router, @vueuse/core 三个包,使用时无需导入。
  • dts: 'src/types/auto-imports.d.ts' 用于生成类型声明文件。
  • eslintrc 启用此项配置为了解决 ESLint 提示 eslint(no-undef) 的问题,会生成一个 ./.eslintrc-auto-import.json 文件,将自动引入的 API 作为全局变量处理,需要在 ESLint 配置文件中作为扩展添加:
// eslint.config.js
const autoImport = JSON.parse(readFileSync('./.eslintrc-auto-import.json', 'utf8'));

module.exports = [
    {
        languageOptions: {
            globals: {
                ...autoImport.globals,
            },
        },
    },
]

🚀 Pinia

Pinia 是 Vue 的一个状态管理库,由 Vue 团队成员创建,会成为 Vuex 的继承者,Vue 文档中也推荐使用 Pinia。与 Vuex 相比,Pinia 提供了一个更简单的 API,可以使用 composition-API 风格,在与 Typescript 一起使用时具有可靠的类型推断支持。

和 Vuex ≤ 4 相比,有许多不同:

  • 不再有 mutations,不需要再区分同步异步去使用不同的方法;
  • 不再需要通过复杂的包装器来支持 Typscript;
  • 不再有模块的概念,但同时支持在 store 中使用其他 store;

定义 store

store 使用 defineStore() 定义,有三种传参格式:

defineStore(id, options);
defineStore(options);
defineStore(id, storeSetup, options?);

其中 id 可以通过第一个参数传递,如果不存在,则通过 options.id 获取,作为唯一的名称。传参最主要的区别是 optionsstoreSetupoptions 是一个对象,包含 state, getters, actions,和 Vuex 类似:

import { defineStore } from 'pinia';

export const useCountStore = defineStore('counter', {
    state: () => ({
        counter: 0,
    }),
    getters: {
        doubleCount: (state) => state.counter * 2,
    },
    actions: {
        increment() {
            this.counter++;
        },
    },
})

第三种传参方式,storeSetup 参数是一个函数,和 Vue setup 方法类似,这也是更推荐的写法:

import { defineStore } from 'pinia';

export const useCountStore = defineStore('counter', () => {
    const counter = ref(0);
    const doubleCount = computed(() => counter.value * 2);
    const increment = () => counter.value++;

    return { counter, doubleCount, increment };
})

可以根据需要定义任意多个 store,并且应该放在不同的文件中,如:

src
└── store
    ├── user.ts
    ├── counter.ts
    └── base.ts

使用 store

<template>
    <div>counter: {{ count.counter }}</div>
    <div>double count: {{ count.doubleCount }}</div>
    <button @click="count.increment">increment</button>
</template>

<script lang="ts" setup>
import { useCountStore } from '@/store/counter';

const count = useCountStore();
watchEffect(() => {
    console.log(count.counter);
});
</script>

store 是一个用 reactive 包装的对象,可以使用 storeToRefs 实现不丢失响应性的情况下对返回的对象进行解构/展开:

import { useCountStore } from '@/store/counter';
import { storeToRefs } from 'pinia';

const store = useCountStore();
const { counter } = storeToRefs(store); // store.counter

🚀 图标

BDB5 过 vite-plugin-import-icons vite 插件实现图标组件化,可以将本地图标包装成组件,还有自动引入按需加载的功能。

⚙️ 配置

// vite.config.ts
import path from 'path';
import ImportIcons, { ImportIconsResolver } from 'vite-plugin-import-icons';

export default defineConfig({
    plugins: [
        Components({
            resolvers: [
                ImportIconsResolver(),
            ],
        }),
        ImportIcons({
            collections: {
              	icons: path.resolve(__dirname, './src/assets/icons'),
            },
        }),
    ],
});

配置说明:

  • ImportIconsResolver 用于将组件化后的图标组件自动引入,可以直接在 template 中使用。
  • collections 用于加载图标,将 './src/assets/icons' 目录下所有 svg 作为一个图标集。

项目中使用了 Typescript,还需要添加类型声明文件 tsconfig.json:

{
    "compilerOptions": {
        "types": [
            "vite-plugin-import-icons/types",
        ]
    }
}

🧐 使用

只需要把 svg 文件放到 ‘./src/assets/icons’ 目录即可,图标集为 ‘icons’,图标名为文件名,推荐使用小写字母,多个单词用短横线链接(kebab-case):

src
└─ asstes
    └─ icons
        └─ about.svg
<template>
    <icons-about></icons-about>
</template>

图标自动加载和组件自动加载一样,会生成对应的模块声明:

// src/types/components.d.ts

declare module 'vue' {
    export interface GlobalComponents {
        IconsHome: typeof import('~icons/icons/home')['default']
    }
}

如果不使用组件自动加载功能,则需要先 import :

<template>
    <icons-about></icons-about>
</template>
<script setup lang="ts">
import IconsAbout from '~icons/icons/about’;
</script>

引入图标的路径 ~icons/* 是一个虚拟路径,由插件处理后,找到真实的 svg 文件,然后包装成 vue 组件返回。

批量引入

vite-plugin-import-icons 插件提供了一个 import.meta.icons 函数,用于一次性引入多个图标。

<template>
    <component v-for="(icon, name) in icons" :is="icon" :key="name"></component>
</template>
<script>
const icons = import.meta.icons('icons', 'menu-*')
</script>

和 iconfont 字体图标比较

在 iconfont 上把所有需要的图标加入项目,再以 font-class 的方式使用是一个比较常见的做法,不过有以下问题:

  • 首先需要先在平台上添加图标到项目,然后下载图标,最后再替换本地的文件,过程更繁琐;
  • 文件包含所有图标,无法按需加载;
  • 平台账号丢失,只能新建一个图标项目;
  • 多色图标需要换用 svg 或者图片,造成项目中图标使用风格不统一;

🚀 UnoCSS

UnoCSS 是高性能且极具灵活性的即时原子化 CSS 引擎。

⚙️ 配置

UnoCSS 的配置文件是 uno.config.ts,需要在项目入口文件中引入相关 CSS:

// main.ts

// 'uno:[layer-name].css'
import 'uno:components.css';
// layers that are not 'components' and 'utilities' will fallback to here
import 'uno.css';
// your own CSS
import './assets/styles/main.less';
// "utilities" layer will have the highest priority
import 'uno:utilities.css';

工具类

工具类的详细介绍可查看文档 https://windicss.org/utilities/,也可以通过搜索快速找到需要的类。

VS Code 插件

UnoCSS Intellisense 通过提供给 Visual Studio Code 用户一些特性的方式来提高 UnoCSS 的开发体验,例如:自动补全、语法高亮。

🚀 样式

项目中依然采用 Less 作为 CSS 预处理器。

./src/assets/styles/main.less 可用于存放公共样式。

🚀 Stylelint

建议安装编辑器 stylelint 插件,并开启保存时自动修复。

vscode settings.json:

{
    "editor.codeActionsOnSave": {
        "source.fixAll.stylelint": true
    }
}

🚀 ESLint

.eslintrc-auto-import.json 引入的是一些全局变量的配置,为了解决 unplugin-auto-import ESLint 报错的问题

项目中使用了 prettier,但无需安装 prettier 插件, 因为 eslint-plugin-prettier 插件可以通过 eslint 提示错误以及自动修复。

🚀 版本控制

  • 使用 lint-staged 在提交代码前执行 pnpm lintpnpm stylelint,防止不规范的代码推送到远程仓库。
  • 使用 Commitizen + Commitlint 对 commit message 做格式校验,可以使用 git cz  代替 git commit 生成符合规范的 message ,如 feat(api): xxx

需要先全局安装 commitizen:pnpm add -g commitizen

About

✨ Vite + Vue3 + TS template

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0