一、前言
需要的环境:
开发工具:VsCode、Visual Studio、sql server
前端:Vue3、Vite、TypeScript、SCSS、Element Plus、Router、axios、Vuex
后端:.NET6、Automapper、Autofac、Sql sugar、JWT、Log4Net
vite官方文档
二、创建vite项目
npm install -g pnpm
pnpm create vite@latest vvt
输入项目名称:vvt
选择:vue
选择:TypeScript
完成
生成的目录结构如下:
│ .gitignore
│ index.html
│ list.txt
│ package.json # 项目配置文件,标题、版本、模块版本等
│ README.md
│ tsconfig.json # TS配置文件
│ tsconfig.node.json
│ vite.config.ts # Vite配置文件
│
├─.vscode
│ extensions.json
│
├─public # 公共资源
│ vite.svg
│
└─src # 项目目录
│ App.vue # 根组件
│ main.ts # 根函数入口、全局配置
│ style.css
│ vite-env.d.ts
│
├─assets # 静态资源
│ vue.svg
│
└─components # 组件
HelloWorld.vue
三、安装依赖
pnpm i
四、安装SCSS
pnpm install sass --save
接下来可以这样使用:
<style lang="scss" ...
五、package.json配置
可以配置一下private、version等信息,可以加入license标签,进行协议生成。
六、Element Plus的安装与使用
pnpm install element-plus --save
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
七、路由的安装与使用
pnpm install vue-router@next --save
新建src/router目录,目录下新建index.ts,写入如下代码:
import { createRouter, createWebHistory } from 'vue-router'
import HomePage from "../pages/HomePage.vue"
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: HomePage }
]
})
export default router
main.ts中导入:
import router from './router'
app.use(router)
改造App.vue
<template>
<router-view />
</template>
八、状态管理
pnpm install vuex@next --save
src下新建文件夹vuex,新建文件index.ts
main.ts
import store from './vuex/index'
app.use(store)
附录:如下是另一个流程分支,是之前做一些特殊功能的测试版本。
五、安装vue-router
pnpm i vue-router -D
新建src\modules文件夹来做一些项目的核心模块配置,比如router、pinia等等。
在文件夹下创建router.ts文件(这个文件会在后面进行更改,为了实现框架搭建,一步步来)。
import { createRouter, createWebHistory } from "vue-router"
const router = createRouter({
routes: [],
history: createWebHistory()
})
export default router
六、注册路由
main.ts:
import App from './App.vue'
import { createApp } from 'vue'
import './style.css'
import router from "./modules/router"
const app = createApp(App)
app.use(router)
app.mount('#app')
七、新建页面文件夹
新建src/pages文件夹来放项目的页面,注意文件夹名称需要为pages,很多项目中定义为views,由于框架后面引用了很多有用的插件,插件默认配置为pages,为了方便,采用pages作为文件夹名称。
八、新建src/pages/home.vue
建议的文件定义模式如下,注意大小写字母的区别:
pages文件夹\
|--home.vue\
|--about文件夹\
|--|--index.vue\
|--|--Component.vue
home.vue内容:
<template>
我是首页
</template>
about/index.vue内容:
<template>
我是about页
</template>
九、App.vue配置路由出口
<template>
<router-view />
</template>
十、配置Home路由
import { createRouter, createWebHistory } from "vue-router"
const router = createRouter({
routes: [
{
name: "首页",
path: "/home",
component: () => import("../pages/home.vue")
},
{
name: "关于",
path: "/about",
component: () => import("../pages/about/index.vue")
}
],
history: createWebHistory()
})
export default router
十一、安装pinia
pnpm i pinia -D
十二、配置pinia
新建src/modules/pinia.ts
import { createPinia } from "pinia"
const pinia = createPinia()
export default pinia
十三、main.ts中引入
import pinia from './modules/pinia'
app.use(pinia)
十四、新建src/stores文件夹
新建src/stores文件夹,注意stores名称,同样于pages,这个文件夹名称在后面引入的组件中是作为默认名称存在的,所以不要改为其它名称。
在该文件夹下创建counterStore.ts,注意在该文件夹下创建的文件均需要以Store结尾,同样作为约定,这也是由后面引入的插件规则来决定的。
import { defineStore } from "pinia"
export const counterStore = defineStore("counter", {
state() {
return {
num: 1
}
},
actions: {
inc() {
this.num++
}
}
})
十五、使用pinia
<script lang="ts" setup>
import { counterStore } from "../stores/counterStore"
const counter = counterStore()
</script>
<template>
<div @click="counter.inc()">
我是首页{{ counter.num }}
</div>
</template>
十六、小结
modules文件夹主要用来放项目核心模块。
pages文件夹主要用来放页面,注意命名。
十七、在components下创建组件
foo.vue
<template>
我是foo
</template>
十八、传统方式引入组件
import foo from "../components/foo.vue"
<foo />
十九、按需引入组件
是否可以实现不用手写import,像element plus等组件那样实现按需引入,直接使用?这里需要使用一个组件unplugin-vue-components。
安装:
pnpm i unplugin-vue-components -D
配置,在vite.config.ts中引入:
import Components from "unplugin-vue-components/vite"
export default defineConfig({
plugins: [..., Components()]
})
将十八小节的import注释
// import foo from "../components/foo.vue"
二十、Element Plus、Native UI的按需引入
安装
pnpm i -D naive-ui
pnpm i -D vant
vite.config.ts:
import {
AntDesignVueResolver,
ElementPlusResolver,
VantResolver,
NaiveUiResolver
} from "unplugin-vue-components/resolvers"
export default defineConfig({
plugins: [..., Components({
resolvers: [NaiveUiResolver(), VantResolver()]
})]
})
直接使用:
<n-button>abc</n-button>
二十一、api的自动引入
这里主要用来解决import { ref } from 'vue'的问题。这里用到了unplugin-auto-import插件。
安装:
pnpm i -D unplugin-auto-import
在vite.config.ts中配置:
import AutoImport from "unplugin-auto-import/vite"
export default defineConfig({
plugins: [
...
AutoImport({
imports: ["vue", "vue-router", "pinia"]
})
...
]
})
使用:
const val = ref(100)
{{ val }}
二十二、小节
截至当前,应用程序可以正常运行,原工程目录下多出了auto-imports.d.ts、components.d.ts两个文件。打开auto-imports.d.ts、components.d.ts,发现这两个文件的内容是自动构建的。
需要注意的是项目本身不在上述两个范畴内的自定义组件还是需要import,比如stores下的组件,可能未来还有一些工具函数组件,这个随后再说。
存在的问题:
components.d.ts存在报错:找不到模块“./src/components/foo.vue”或其相应的类型声明。ts(2307)
Home.vue下存在报错:找不到名称“ref”。ts(2304)
但是程序运行是没有问题的,这些报错主要是类型声明的问题,这个随后再说。
附:解决上述的问题
vite.config.ts
import AutoImport from 'unplugin-auto-import/vite';
plugins:
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
dts: './auto-imports.d.ts',
eslintrc: {
enabled: true,
globalsPropValue: true,
filepath: './.eslintrc-auto-import.json',
},
}),
.eslintrc.json
"extends": [
...
".eslintrc-auto-import.json"
],
tsconfig.json
"include": [... "auto-imports.d.ts"],
二十三、解决store的自动引入
api自动导入插件支持这样的属性:
AutoImport({
...
dirs: ['src/stores/**/*.ts']
})
这样的话只要src/stores下有export default,可以直接按需导入。
只要stores下的文件符合Store结尾即可自动引入,对十二节的store文件进行修改:
src/stores/counterStore.ts
import { defineStore } from "pinia"
export default defineStore("counter", {
state() {
return {
num: 1
}
},
actions: {
inc() {
this.num++
}
}
})
在文件中直接使用:
const counter = counterStore()
{{ counter.num }}
二十三、解决自定义组件的自动引入
创建src/composables文件夹,创建有导出的ts文件。同时在vite.config.ts中配置自动导入插件:
import AutoImports from "unplugin-auto-import/vite"
AutoImports({
...
dirs: ['src/composables/**/*.ts']
}),
注意:unplugin-auto-import更新还是比较快的,为了实现stores和composables的引入支持,后来形成了默认规则,而自定义的模块这里只要配置dirs即可实现响应目录下的文件自定引入。
需要注意的是:由于composables和stores的意义,composables中的文件已use开头,stores已Store结尾,这主要形成一个项目约定。
直接使用:
console.log(useFoo)
二十四、文件路由
安装vite-plugin-pages。
pnpm install -D vite-plugin-pages
vite.config.ts引入:
import Pages from "vite-plugin-pages"
export default defineConfig({
plugins: [
...
Pages(),
...
]
})
修改src/modules/router.ts文件:
import routes from "~pages"
import { createRouter, createWebHistory } from "vue-router"
const router = createRouter({
routes,
history: createWebHistory()
})
export default router
解决类型问题:
在某个类型声明文件中引入/// <reference types='vite-plugin-pages/client' />
二十五、布局
为了在一些子组件中避免引入header、footer等公共组件,这里采用layout来做这一块的功能。
安装:
pnpm i vite-plugin-vue-layouts -D
vite.config.ts注册:
import Layouts from "vite-plugin-vue-layouts"
export default defineConfig({
plugins: [
...
Layouts(),
...
]
})
再次对router.ts进行更改:
import { createRouter, createWebHistory } from "vue-router"
import { setupLayouts } from "virtual:generated-layouts"
import generatedRoutes from "virtual:generated-pages"
const routes = setupLayouts(generatedRoutes)
const router = createRouter({
routes,
history: createWebHistory()
})
export default router
新建src/layouts文件夹,新建一个布局文件default.vue:
<template>
asdfasdfsad
<router-view />
</template>
可以看到这个布局已经默认启用了。
怎么在vue文件中使用,加入一个这样的节点即可:
<route>
{
meta: {
layout: 'custom'
}
}
</route>