特色
-
📦 组件自动化引入
-
🌈 Primevue - Vue.js UI 套件,提高开发效率
-
🎨 UnoCSS - 高性能且极具灵活性的即时原子化 CSS 引擎
-
🔥 使用 新的
<script setup>
语法 -
📥 API 自动加载 - 直接使用 Composition API 无需引入
-
🌍 API 采用模块化自动导入方式 根据demo.js文件设置接口,以API_xxx_method的方式命名,在请求时无需导入 直接使用useRequest()函数返回参数以解构的方式获取,拿到即为写入的接口
-
🐶 husky + lint-staged - Git提交自动检测格式化代码,解放双手
-
🎢 无TS,释放你的野性
进入正题
node版本必须是 >=18.18.0
创建基础模板
1pnpm create vite my-vue-app --template vue
详细请看➡️cn.vitejs.dev/guide/#scaf…
得到以下目录结构⬇️
配置API自动化导入
安装依赖
1pnpm i unplugin-auto-import -D
在vite.config.js中配置
1import { defineConfig } from 'vite'
2import vue from '@vitejs/plugin-vue'
3import AutoImport from 'unplugin-auto-import/vite'
4
5
6export default defineConfig({
7 plugins: [
8 vue(),
9 AutoImport({
10 imports: [
11 'vue',
12 'vue-router',
13 'pinia',
14 '@vueuse/core',
15
16
17
18
19 ],
20 eslintrc: {
21 enabled: true,
22 filepath: './.eslintrc-auto-import.json',
23 globalsPropValue: true
24 }
25 }),
26 ],
27})
28
此时在App.vue
中不用引入直接可以使用Vue的api
1<script setup>
2 const title = ref('Hello World!')
3</script>
配置组件自动化导入
安装依赖
1pnpm i unplugin-vue-components -D
在vite.config.js中配置
1import { defineConfig } from 'vite'
2import vue from '@vitejs/plugin-vue'
3import Components from 'unplugin-vue-components/vite'
4
5
6export default defineConfig({
7 plugins: [
8 vue(),
9 Components({
10 dirs: ['src/components'],
11 dts: false,
12 resolvers: [],
13 include: [/\.vue$/, /\.vue\?vue/, /\.jsx$/]
14 }),
15 ],
16})
17
src/components
下新建 的组件 ,此时在App.vue
中不用引入直接可以使用
1<template>
2 <div>
3 <HelloWorld msg="Hello Vue 3.0 + Vite" />
4 </div>
5</template>
6
7<script setup></script>
配置UnoCss
安装依赖
1pnpm i unocss -D
直接插入以下代码⬇️(没有对应文件的自行创建)
unocss.config.js
1import {
2 defineConfig,
3 presetAttributify,
4 presetIcons,
5 presetTypography,
6 presetUno,
7 presetWebFonts,
8 transformerDirectives,
9 transformerVariantGroup
10} from 'unocss'
11
12
13export default defineConfig({
14 shortcuts: [
15
16 ],
17 theme: {
18 colors: {
19
20 }
21 },
22 presets: [
23 presetUno(),
24 presetAttributify(),
25 presetIcons(),
26 presetTypography(),
27 presetWebFonts({
28 fonts: {
29
30 }
31 })
32 ],
33 transformers: [transformerDirectives(), transformerVariantGroup()]
34})
在main.js中引入样式
1import { createApp } from 'vue'
2import App from './App.vue'
3
4import './style.css'
5import 'virtual:uno.css'
6
7async function bootstrap() {
8 const app = createApp(App)
9 app.mount('#app')
10}
11bootstrap()
在vite.config.js中配置
1import { defineConfig } from 'vite'
2import vue from '@vitejs/plugin-vue'
3import Unocss from 'unocss/vite'
4
5
6export default defineConfig({
7 plugins: [
8 vue(),
9
10 Unocss({}),
11
12 ],
13})
14
接入Primevue
安装依赖
1pnpm add primevue @primevue/themes
在main.js中配置
1import { createApp } from 'vue'
2import App from './App.vue'
3import PrimeVue from 'primevue/config'
4import Nora from '@primevue/themes/nora'
5
6import './style.css'
7import 'virtual:uno.css'
8
9async function bootstrap() {
10 const app = createApp(App)
11
12 app.use(PrimeVue, {
13 theme: {
14 preset: Nora
15 }
16 })
17
18 app.mount('#app')
19}
20bootstrap()
在vite.config.js中配置组件自动导入
1import { defineConfig } from 'vite'
2import vue from '@vitejs/plugin-vue'
3import Components from 'unplugin-vue-components/vite'
4import { PrimeVueResolver } from '@primevue/auto-import-resolver'
5
6
7export default defineConfig({
8 plugins: [
9 vue(),
10 Components({
11 dirs: ['src/components'],
12 dts: false,
13 resolvers: [PrimeVueResolver()],
14 include: [/\.vue$/, /\.vue\?vue/, /\.jsx$/]
15 }),
16 ],
17})
此时在App.vue
中不用引入直接可以使用
1<div class="card flex justify-center flex-wrap gap-4">
2 <Button label="Primary" />
3 <Button label="Secondary" severity="secondary" />
4 <Button label="Success" severity="success" />
5 <Button label="Info" severity="info" />
6 <Button label="Warn" severity="warn" />
7 <Button label="Help" severity="help" />
8 <Button label="Danger" severity="danger" />
9 <Button label="Contrast" severity="contrast" />
10</div>
更多组件请看➡️ primevue.org/button/
接入VueRouter4
安装依赖
1pnpm i vue-router@4
创建以下文件夹以及文件
直接插入以下代码⬇️
helper.js
1 * 设置页面标题
2 * @param {Object} to 路由对象
3 */
4export const usePageTitle = (to) => {
5 const projectTitle = import.meta.env.VITE_APP_TITLE
6 const rawTitle = normalizeTitle(to.meta.title)
7 const title = useTitle()
8 title.value = rawTitle ? `${projectTitle} | ${rawTitle}` : projectTitle
9 function normalizeTitle(raw) {
10 return typeof raw === 'function' ? raw() : raw
11 }
12}
index.js
1import { createRouter, createWebHashHistory } from 'vue-router'
2import { usePageTitle } from './helper'
3
4
5const router = createRouter({
6 history: createWebHashHistory(import.meta.env.BASE_URL),
7 routes: [
8 {
9 path: '/',
10 name: 'Test',
11
12 component: () => import('@/views/demo/index.vue'),
13 meta: {
14 title: '测试'
15 }
16 },
17 {
18 path: '/:pathMatch(.*)*',
19
20 component: () => import('@/views/system/404/404.vue'),
21 meta: {
22 title: '找不到页面'
23 }
24 }
25 ]
26})
27
28router.beforeEach((to, from, next) => {
29 usePageTitle(to)
30 next()
31})
32
33async function setupRouter(app) {
34 app.use(router)
35}
36
37export { setupRouter }
配置项目全局环境变量
具体请看 ➡️vite.dev/guide/env-a…
.env
1
2VITE_APP_TITLE = 演示项目
3
4
5VITE_APP_PREFIX = demo
6
7
8VITE_APP_API_BASEURL = /
.env.development
1
2VITE_APP_TITLE = 演示项目
3
4
5VITE_APP_PREFIX = demo
6
7
8VITE_APP_API_BASEURL = /
9
10
在main.js中引入
1import { createApp } from 'vue'
2import App from './App.vue'
3import PrimeVue from 'primevue/config'
4import Nora from '@primevue/themes/nora'
5import { setupRouter } from './router'
6
7import './style.css'
8import 'virtual:uno.css'
9
10async function bootstrap() {
11 const app = createApp(App)
12
13 app.use(PrimeVue, {
14 theme: {
15 preset: Nora
16 }
17 })
18
19 await setupRouter(app)
20
21 app.mount('#app')
22}
23bootstrap()
封装Axios
Vite4、Vue3、Axios 针对请求模块化封装搭配自动化导入(简单易用)
接入Pinia状态管理
安装依赖
1pnpm i pinia
创建以下文件夹以及文件
直接插入以下代码⬇️
index.js
1import { createPinia } from 'pinia'
2export const piniaStore = createPinia()
3export function setupStore(app) {
4 app.use(piniaStore)
5}
demo.js
1import { piniaStore } from '@/stores'
2export const useCounterStore = defineStore('counter', () => {
3 const count = ref(0)
4 const doubleCount = computed(() => count.value * 2)
5 function increment() {
6 count.value++
7 }
8
9 return { count, doubleCount, increment }
10})
11
12export function useOutsideCounterStore() {
13 return useCounterStore(piniaStore)
14}
接入Prerttier + OXLint + ESLint
安装依赖
1pnpm i oxlint prettier eslint-plugin-oxlint eslint-plugin-prettier -D
安装并配置ESLint
1pnpm create @eslint/config@latest
根据响应提示选择,以下是我的选择⬇️
执行完后会自动创建eslint.config.js
配置文件,以及对应依赖包🤩
直接插入以下代码⬇️(没有对应文件的自行创建)
eslint.config.js
1import path from 'path'
2import globals from 'globals'
3import pluginJs from '@eslint/js'
4import pluginVue from 'eslint-plugin-vue'
5import VueEslintParser from 'vue-eslint-parser'
6import prettier from 'eslint-plugin-prettier'
7import oxlint from 'eslint-plugin-oxlint'
8import { FlatCompat } from '@eslint/eslintrc'
9import { fileURLToPath } from 'url'
10
11const __filename = fileURLToPath(import.meta.url)
12const __dirname = path.dirname(__filename)
13
14const compat = new FlatCompat({
15 baseDirectory: __dirname
16})
17
18
19export default [
20 {
21 files: ['**/*.{js,mjs,cjs,vue}']
22 },
23 {
24 languageOptions: {
25 globals: {
26 ...globals.browser,
27 ...globals.node
28 },
29 parser: VueEslintParser
30 }
31 },
32
33 pluginJs.configs.recommended,
34
35 ...pluginVue.configs['flat/essential'],
36
37 ...compat.extends('./.eslintrc-auto-import.json'),
38
39 oxlint.configs['flat/recommended'],
40
41 {
42 rules: {
43 'no-var': 'error',
44 'no-multiple-empty-lines': ['warn', { max: 1 }],
45 'no-unexpected-multiline': 'error',
46 'no-useless-escape': 'off',
47
48 'vue/multi-word-component-names': 0
49 }
50 },
51
52 * prettier 配置
53 * 会合并根目录下的prettier.config.js 文件
54 * @see https://prettier.io/docs/en/options
55 * https://github.com/prettier/eslint-plugin-prettier/issues/634
56 */
57 {
58 plugins: {
59 prettier
60 },
61 rules: {
62 ...prettier.configs.recommended.rules
63 }
64 },
65
66 {
67 ignores: [
68 '**/dist',
69 './src/main.ts',
70 '.vscode',
71 '.idea',
72 '*.sh',
73 '**/node_modules',
74 '*.md',
75 '*.woff',
76 '*.woff',
77 '*.ttf',
78 'yarn.lock',
79 'package-lock.json',
80 '/public',
81 '/docs',
82 '**/output',
83 '.husky',
84 '.local',
85 '/bin',
86 'Dockerfile'
87 ]
88 }
89]
prettier.config.js
1export default {
2
3 printWidth: 100,
4
5 tabWidth: 2,
6
7 useTabs: false,
8
9 semi: false,
10 vueIndentScriptAndStyle: true,
11
12 singleQuote: true,
13
14 quoteProps: 'as-needed',
15
16 trailingComma: 'none',
17
18 jsxSingleQuote: true,
19
20 bracketSpacing: true,
21 proseWrap: 'never',
22 htmlWhitespaceSensitivity: 'strict',
23 endOfLine: 'auto'
24}
.editorconfig
1root = true
2
3
4[*]
5
6charset = utf-8
7
8indent_style = space
9
10indent_size = 2
11
12end_of_line = lf
13
14insert_final_newline = true
15
16trim_trailing_whitespace = true
17
18
19[*.md]
20trim_trailing_whitespace = false
配置package.json文件
1"scripts": {
2 "dev": "vite --host",
3 "build": "vite build",
4 "preview": "vite preview",
5 "lint": "oxlint && eslint",
6 "lint:fix": "oxlint --fix && eslint --fix"
7},
此时终端中执行 pnpm lint
或者 pnpm lint:fix
就会检测并修复代码 🤩
检测结果以 oxlint形式展现⬇️
接入 husky + lint-staged(可选)
安装依赖
1pnpm i husky lint-staged -D
执行 pnpm exec husky init
并且在 package.json的 scripts里面增加 "prepare": "husky init"
,(其他人安装后会自动执行) 根目录会生成 .hushy 文件夹。
直接插入以下代码⬇️(没有对应文件的自行创建)
lint-staged.config.js
1export default {
2 '**/*.{html,vue,ts,cjs,json,md}': ['prettier --write'],
3 '**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx,vue,astro,svelte}': ['oxlint --fix && eslint --fix']
4}
通过下面命令在钩子文件中添加内容⬇️
1echo "npx --no-install -- lint-staged" > .husky/pre-commit
2echo "npx --no-install commitlint --edit $1" > .husky/commit-msg
注意⚠️⚠️⚠️ : 上面命令钩子不会执行 当进行git提交时会出现下面问题⬇️
说是无法执行这个二进制文件 ,解决方案如下⬇️ 在vscode编辑器底部操作栏 会显示当前文件编码格式 默认为➡️
点击后选择
然后再次执行git提交命令就可以了🤙
接入commitizen + commitlint + cz-git(可选)
安装依赖
1pnpm i commitizen commitlint @commitlint/cli @commitlint/config-conventional cz-git -D
commitizen 基于Node.js的 git commit 命令行工具,辅助生成标准化规范化的 commit message
committlint 检查你的提交消息是否符合常规的提交格式。
cz-git 标准输出格式的 commitizen 适配器
直接插入以下代码⬇️(没有对应文件的自行创建)
commitlint.config.js
1export default {
2 extends: ['@commitlint/config-conventional'],
3 rules: {
4 'type-enum': [
5 2,
6 'always',
7 [
8 'feat',
9 'fix',
10 'perf',
11 'style',
12 'docs',
13 'test',
14 'refactor',
15 'build',
16 'ci',
17 'init',
18 'chore',
19 'revert',
20 'wip',
21 'workflow',
22 'types',
23 'release'
24 ]
25 ],
26 'subject-case': [0]
27 },
28 prompt: {
29 alias: { fd: 'docs: fix typos' },
30 messages: {
31 type: '选择你要提交的类型 :',
32 scope: '选择一个提交范围(可选):',
33 customScope: '请输入自定义的提交范围 :',
34 subject: '填写简短精炼的变更描述 :\n',
35 body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
36 breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
37 footerPrefixesSelect: '选择关联issue前缀(可选):',
38 customFooterPrefix: '输入自定义issue前缀 :',
39 footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
40 confirmCommit: '是否提交或修改commit ?'
41 },
42 types: [
43 { value: 'feat', name: 'feat: 🤩 新增功能 | A new feature', emoji: ':sparkles:' },
44 { value: 'fix', name: 'fix: 🐛 修复缺陷 | A bug fix', emoji: ':bug:' },
45 { value: 'docs', name: 'docs: 📝 文档更新 | Documentation only changes', emoji: ':memo:' },
46 {
47 value: 'style',
48 name: 'style: 🎨 代码格式 | Changes that do not affect the meaning of the code',
49 emoji: ':lipstick:'
50 },
51 {
52 value: 'refactor',
53 name: 'refactor: ♻️ 代码重构 | A code change that neither fixes a bug nor adds a feature',
54 emoji: ':recycle:'
55 },
56 {
57 value: 'perf',
58 name: 'perf: ⚡ 性能提升 | A code change that improves performance',
59 emoji: ':zap:'
60 },
61 {
62 value: 'test',
63 name: 'test: ✅ 测试相关 | Adding missing tests or correcting existing tests',
64 emoji: ':white_check_mark:'
65 },
66 {
67 value: 'build',
68 name: 'build: 📦️ 构建相关 | Changes that affect the build system or external dependencies',
69 emoji: ':package:'
70 },
71 {
72 value: 'ci',
73 name: 'ci: 🎡 持续集成 | Changes to our CI configuration files and scripts',
74 emoji: ':ferris_wheel:'
75 },
76 { value: 'revert', name: 'revert: ⏪️ 回退代码 | Revert to a commit', emoji: ':rewind:' },
77 {
78 value: 'chore',
79 name: 'chore: 🔨 其他修改 | Other changes that do not modify src or test files',
80 emoji: ':hammer:'
81 }
82 ],
83 useEmoji: true,
84 emojiAlign: 'center',
85 useAI: false,
86 aiNumber: 1,
87 themeColorCode: '',
88 scopes: [],
89 allowCustomScopes: true,
90 allowEmptyScopes: true,
91 customScopesAlign: 'bottom',
92 customScopesAlias: 'custom',
93 emptyScopesAlias: 'empty',
94 upperCaseSubject: false,
95 markBreakingChangeMode: false,
96 allowBreakingChanges: ['feat', 'fix'],
97 breaklineNumber: 100,
98 breaklineChar: '|',
99 skipQuestions: [],
100 issuePrefixes: [
101
102 { value: 'link', name: 'link: 链接 ISSUES 进行中' },
103 { value: 'closed', name: 'closed: 标记 ISSUES 已完成' }
104 ],
105 customIssuePrefixAlign: 'top',
106 emptyIssuePrefixAlias: 'skip',
107 customIssuePrefixAlias: 'custom',
108 allowCustomIssuePrefix: true,
109 allowEmptyIssuePrefix: true,
110 confirmColorize: true,
111 scopeOverrides: undefined,
112 defaultBody: '',
113 defaultIssues: '',
114 defaultScope: '',
115 defaultSubject: ''
116 }
117}
配置package.json文件
1"scripts": {
2 "dev": "vite --host",
3 "build": "vite build",
4 "preview": "vite preview",
5 "lint": "oxlint && eslint",
6 "lint:fix": "oxlint --fix && eslint --fix",
7 "cz": "git-cz"
8},
9"config": {
10 "commitizen": {
11 "path": "node_modules/cz-git"
12 }
13 }
测试
在终端命令行中输入⬇️
1git add .
2
3pnpm cz
然后会出现本次git提交选项
根据需求选择
ctrl + c
终止当前提交
Enter
下一步操作
模板
拉取后 开箱即用 模板地址➡️ github.com/gitboyzcf/v…
样例
此模板开发大屏模板样例➡️ github.com/gitboyzcf/v…