# vueTs
**Repository Path**: lyfcloud/vue-ts
## Basic Information
- **Project Name**: vueTs
- **Description**: 使用vue3.0 + ts 构建的后台系统
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 0
- **Created**: 2021-05-05
- **Last Updated**: 2022-05-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 一、技术栈
- 开发环境:[Node](https://nodejs.org/en/)
- 代码管理:[Git ](https://git-scm.com/)
- 构建工具:[Vite 2.x](https://vitejs.dev/)
- 前端框架:[Vue3.x](https://v3.vuejs.org/)
- 编程语言:[TypeScript](https://www.typescriptlang.org/)
- 路由工具:[Vue Router 4.x](https://next.router.vuejs.org/)
- 状态管理:[Pinia]()
- UI 框架:[Ant-Design-Vue](https://2x.antdv.com/docs/vue/introduce-cn/)
- CSS 预编译:[Less](http://lesscss.cn/)
- HTTP 工具:[Axios](https://axios-http.com/)
## 二、`vite` + `Ts` + `vue3.0`搭建
#### 1. 初始化
- 使用`npm`
```javascript
npm init @vitejs/app
```
- 输入项目名`Project name`: `vue-ts`
- 选择`vue`
- 选择`Typescript`
#### 2. 项目目录
```
vue-ts
|
└───build -- 打包文件
│ │ util.ts -- 打包时的公共方法
│ node_modules -- 项目依赖包的目录
└───public -- 项目公用文件
│ │ favicon.ico -- 网站地址栏前面的小图标
└───src -- 源文件目录
│ │ assets -- 静态文件目录,图片图标,比如网站logo
│ │ components -- Vue3.x的自定义组件目录
│ │ router -- 路由文件
│ │ views -- 视图文件
│ │ App.vue -- 项目的根组件,单页应用都需要的
│ │ main.ts -- 项目入口文件
│ │ shims-vue.d.ts -- tS识别.vue的辅助文件
│ .gitignore -- git忽略提交文件
│ index.html -- 首页入口文件
│ package-lock.json -- 项目配置文件,锁定版本号
│ package.json -- 项目配置文件
│ tsconfig.json -- ts配置文件
│ vite.config.ts -- vite配置文件
```
#### 3. 配置环境变量
- 创建环境变量
```jade
# .env文件 是所有的env公共配置文件
VITE_PORT=9527
```
```jade
# .env.development 开发环境配置
# 环境名称
VITE_GLOB_NAME = DEVELOPMENT
# 是否删除Console.log
VITE_DROP_CONSOLE = false
```
```jade
# .env.production 生产环境配置
# 环境名称
VITE_GLOB_NAME = PRODUCTION
# 是否删除Console.log
VITE_DROP_CONSOLE = true
```
```jade
# .env.test 测试环境配置
# 环境名称
VITE_GLOB_NAME = TEST
# 是否删除Console.log
VITE_DROP_CONSOLE = false
```
- 修改`package.json`文件
```json
{
"scripts": {
"dev": "vite",
"build:test": "vue-tsc --noEmit && vite build --mode test",
"build:prod": "vue-tsc --noEmit && vite build --mode production",
"serve": "vite preview"
}
}
```
- 修改`vite.config.ts`文件, 增加以下配置
```typescript
import type { UserConfig, ConfigEnv } from 'vite'
import { loadEnv } from 'vite'
import { wrapperEnv } from './build/util'
/**
* @description 获取当前目录
*/
const root: string = process.cwd()
// https://vitejs.dev/config/
export default ({ command, mode }: ConfigEnv): UserConfig => {
const env = loadEnv(mode, root)
const viteEnv = wrapperEnv(env)
const { VITE_PORT } = viteEnv
return {
root,
server: {
port: VITE_PORT
}
}
}
```
- 创建`build`文件夹,并在下面创建一个`util.ts`文件
```typescript
export interface ViteEnv {
VITE_PORT: number
VITE_GLOB_NAME: string
VITE_DROP_CONSOLE: boolean
}
/**
* 读取env环境的配置,并配置到node的全局变量中
*/
export function wrapperEnv(envConfig: any): ViteEnv {
const ret: any = {}
for (const envName of Object.keys(envConfig)) {
ret[envName] = envConfig[envName]
}
process.env = { ...process.env, ...envConfig }
return ret
}
```
#### 4. 配置`alias`
- 在`vite.config.ts`中配置
```typescript
resolve: {
alias: {
"@": resolve(__dirname, "src"),
},
},
```
- 在`tsconfig.json`中 配置
```json
{
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
```
#### 5. 配置路由` vue-router@4`
- 安装
```javascript
npm i vue-router@4
```
- 创建`src/router/index.ts`文件
```typescript
/**
* 路由
*/
import type { RouteRecordRaw } from 'vue-router'
import { createRouter, createWebHistory } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/login/index.vue')
},
{
path: '/',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
```
- 在`main.ts`中引入
```typescript
import router from '@/router/index'
const app = createApp(App)
app.use(router)
app.mount('#app')
```
- 修改`App.vue`文件
```vue
```
#### 6. 配置状态管理`pinia`
- [文档地址](https://pinia.esm.dev/introduction.html)
- 安装
```javascript
npm i pinia@next
```
- 创建`src/store/index.ts`文件
```typescript
import type { App } from 'vue'
import { createPinia } from 'pinia'
const store = createPinia()
export function setupStore(app: App) {
app.use(store)
}
export { store }
```
- 创建`src/store/modules/user.ts`文件
```typescript
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'app-user',
state: () => ({
token: '11111111'
}),
getters: {
getToken(): string {
return this.token
}
},
actions: {
setToken(info: string) {
this.token = info
}
}
})
```
- 在`main.ts`中引入
```typescript
import { createApp } from 'vue'
import { setupStore } from '@/store/index'
const app = createApp(App)
setupStore(app)
app.mount('#app')
```
#### 7. 安装`UI`组件`antd`
- 安装
```js
npm i ant-design-vue@next // UI
npm i vite-plugin-style-import -D // 安装样式按需加载组件
```
- 修改 vite.config.ts
```ts
import styleImport from 'vite-plugin-style-import'
export default ({ command, mode }: ConfigEnv): UserConfig => {
return {
...
plugins: [
...
styleImport({
libs: [
{
libraryName: 'ant-design-vue',
esModule: true,
resolveStyle: (name) => {
return `ant-design-vue/es/${name}/style/index`
}
}
]
})
]
}
}
```
- 创建 antd.ts
```ts
/**
* @description 按需引入antd
*/
import { Button } from 'ant-design-vue'
import { App } from 'vue'
const components = [Button]
export function registerAntdComp(app: App) {
components.forEach((comp: any) => {
app.component(comp.name || comp.displayName, comp)
})
}
```
- 使用
```vue
```
- 在`main.ts`中引入样式
```ts
import { registerAntdComp } from '@/antd'
registerAntdComp(app)
```
#### 8. 安装`css`预处理器`Less`
- 安装
```js
npm i less -D
```
- 更改`main.ts`中`antd`样式的引入
```ts
import('ant-design-vue/dist/antd.less')
// 注意:加上之后`vite`终端会报错
// 报错信息如下:[vite] Internal server error: Inline JavaScript is not enabled. Is it set in your options?
```
- 解决报错, 修改`vite.config.ts`文件,T 添加下面配置
```
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true
}
}
}
```
#### 9. 安装`axios`
- 安装
```js
npm i axios
```
- 新建`src/utils/axios.ts`
```ts
import Axios from 'axios'
const baseURL = 'https://www.baidu.com'
const axios = Axios.create({
baseURL,
timeout: 20000
})
// 请求拦截
axios.interceptors.request.use(
(response) => {
// 可以根据请求数据进行处理
return response
},
(error) => {
return Promise.reject(error)
}
)
// 响应拦截
axios.interceptors.response.use(
(response) => {
// 对返回数据进行统一处理
return response
},
(error) => {
return Promise.reject(error)
}
)
```
## 三、代码规范
#### 1. 集成`Prettier`配置
- 安装`Prettier`
```
npm i prettier -D
```
- 创建`Prettier`的配置文件 `.prettierrc.js`
- 配置`.prettierrc.js`
```js
module.exports = {
useTabs: false,
tabWidth: 2,
printWidth: 100,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: true,
semi: false
}
```
- 使用命令格式化代码
```
npx prettier -w .
```
#### 2. 集成`ESLint`
- 安装
```
npm i eslint -D
```
- 配置`ESLint`
- 执行`npx eslint --init`创建配置文件
- How would you like to use ESLint? **To check syntax, find problems, and enforce code style**
- What type of modules does your project use? **JavaScript modules (import/export)**
- Which framework does your project use? **Vue.js**
- Does your project use TypeScript? **Yes**
- Where does your code run? **Browser 和 Node**
- How would you like to define a style for your project? **Use a popular style guide**
- Which style guide do you want to follow? **Airbnb**
- What format do you want your config file to be in? **JavaScript**
- 生成`ESLint`的配置文件
```js
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: ['plugin:vue/essential', 'airbnb-base'],
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['vue', '@typescript-eslint'],
rules: {}
}
```
#### 3. 解决`Prettier`和`ESLint`冲突
- 安装`eslint-plugin-prettier`将 `Prettier `的规则设置到 `ESLint` 的规则中
- 安装`eslint-config-prettier` 关闭 ESLint 中与 Prettier 中会发生冲突的规则
```
npm i eslint-plugin-prettier eslint-config-prettier -D
```
- 最后形成优先级:`Prettier 配置规则` > `ESLint 配置规则`
- 在`.eslintrc.js`中添加`prettier`插件
```js
module.exports = {
...
extends: [
'plugin:vue/essential',
'airbnb-base',
'plugin:prettier/recommended' // 添加 prettier 插件
],
...
}
```