Vue3项目搭建学习笔记

  • 参考王红元老师vue课程

创建项目

vue create vue3-ts-cms

项目搭建规范

集成editorconfig配置

  • VSCode需要安装一个插件:EditorConfig for VS Code

  • 新建文件  .editorconfig
# http://editorconfig.orgroot = true[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false

使用prettier工具

  • 安装插件prettier

  • Prettier 是一款强大的代码格式化工具,支持 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等语言,基本上前端能用到的文件格式它都可以搞定,是当下最流行的代码格式化工具。
  • 安装prettier
npm install prettier -D
  • 新建并配置.prettierrc文件:

    • useTabs:使用tab缩进还是空格缩进,选择false;
    • tabWidth:tab是空格的情况下,是几个空格,选择2个;
    • printWidth:当行字符的长度,推荐80,也有人喜欢100或者120;
    • singleQuote:使用单引号还是双引号,选择true,使用单引号;
    • trailingComma:在多行输入的尾逗号是否添加,设置为 none
    • semi:语句末尾是否要加分号,默认值true,选择false表示不加;
{"useTabs": false,"tabWidth": 2,"printWidth": 80,"singleQuote": true,"trailingComma": "none","semi": false,"endOfLine":"lf"
}
  • 创建.prettierignore忽略文件
/dist/*
.local
.output.js
/node_modules/****/*.svg
**/*.sh/public/*
  • 在package.json中配置一个scripts:
"prettier": "prettier --write ."

  • 注意:如果安装Vetur 按Ctrl+ S保存,可能无效,需要禁用Vetur

  • 或者右键进行格式化

使用ESLint检测

  • 1.在前面创建项目的时候,我们就选择了ESLint,所以Vue会默认帮助我们配置需要的ESLint环境。
  • 2.VSCode需要安装ESLint插件:

  • 解决eslint和prettier冲突的问题:
  • 安装插件:(vue在创建项目时,如果选择prettier,那么这两个插件会自动安装)
npm i eslint-plugin-prettier eslint-config-prettier -D

.eslintrc.js 添加prettier插件:

 'plugin:prettier/recommended'

git Husky和eslint

  • 我们希望保证代码仓库中的代码都是符合eslint规范的;
  • 那么我们需要在组员执行 git commit 命令的时候对其进行校验,如果不符合eslint规范,那么自动通过规范进行修复;
  • husky是一个git hook工具,可以帮助我们触发git提交的各个阶段:pre-commit、commit-msg、pre-push
  • 这里我们可以使用自动配置命令:
npx husky-init && npm install
  • 注:安装npx  :  npm install -g npx。如果上面语句无法一起执行,就分两次执行。

  • 这个时候我们执行git commit的时候会自动对代码进行lint校验

git commit规范

  • Commitizen 是一个帮助我们编写规范 commit message 的工具;
  • 1.安装Commitizen
npm install commitizen -D
  • 2.安装cz-conventional-changelog,并且初始化cz-conventional-changelog:
npx commitizen init cz-conventional-changelog --save-dev --save-exact
  • 这个命令会帮助我们安装cz-conventional-changelog:

  • 并且在package.json中进行配置:

  • 这个时候我们提交代码需要使用:
npx cz
  • 第一步是选择type,本次更新的类型:
Type 作用
feat 新增特性 (feature)
fix 修复 Bug(bug fix)
docs 修改文档 (documentation)
style 代码格式修改(white-space, formatting, missing semi colons, etc)
refactor 代码重构(refactor)
perf 改善性能(A code change that improves performance)
test 测试(when adding missing tests)
build 变更项目构建或外部依赖(例如 scopes: webpack、gulp、npm 等)
ci 更改持续集成软件的配置文件和 package 中的 scripts 命令,例如 scopes: Travis, Circle 等
chore 变更构建流程或辅助工具(比如更改测试环境)
revert 代码回退
  • 第二步选择本次修改的范围(作用域)

  • 第三步选择提交的信息

  • 第四步提交详细的描述信息

  • 第五步是否是一次重大的更改

  • 第六步是否影响某个open issue

  • 也可以在scripts中构建一个命令来执行 cz:

    • "commit": "cz"

代码提交验证

  • 通过commitlint来限制提交格式
  • 1.安装 @commitlint/config-conventional 和 @commitlint/cli
npm i @commitlint/config-conventional @commitlint/cli -D
  • 2.在根目录创建  commitlint.config.js  文件,配置commitlint
module.exports = {extends: ['@commitlint/config-conventional']
}
  • 3.使用husky生成commit-msg文件,验证提交信息:
npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"
  • 生成文件:

  • 配置脚本命令:

  • 使用  npm run commit:

第三方库集成

vue.config.js配置

  • 配置参数:配置参考 | Vue CLI

vue.config.js有三种配置方式:

  • 方式一:直接通过CLI提供给我们的选项来配置:

    • 比如publicPath:配置应用程序部署的子目录(默认是 /,相当于部署在 https://www.my-app.com/);

    • 比如outputDir:修改输出的文件夹;

  • 方式二:通过configureWebpack修改webpack的配置:

    • 可以是一个对象,直接会被合并;

    • 可以是一个函数,会接收一个config,可以通过config来修改配置;

  • 方式三:通过chainWebpack修改webpack的配置:

    • 是一个函数,会接收一个基于 webpack-chain 的config对象,可以对配置进行修改;

const path = require('path')module.exports = {// 1.配置方式一: CLI提供的属性outputDir: './build',publicPath: './',// 2.配置方式二: 和webpack属性完全一致, 最后会进行合并// configureWebpack: {//   resolve: {//     alias: {//       components: '@/components'//     }//   }// },// configureWebpack: (config) => {//   config.resolve.alias = {//     '@': path.resolve(__dirname, 'src'),//     components: '@/components'//   }// }// 3.配置方式三:chainWebpack: (config) => {config.resolve.alias.set('@', path.resolve(__dirname, 'src')).set('components', '@/components')}
}

vue-router集成

  • 安装vue-router的最新版本:
npm install vue-router@next
  • 创建router对象:

  • index.ts:
import { createRouter, createWebHashHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'const routes: RouteRecordRaw[] = [{path: '/',redirect: '/login'},{path: '/login',component: () => import('@/views/login/login.vue')},{path: '/main',component: () => import('@/views/main/main.vue')}
]const router = createRouter({routes,history: createWebHashHistory()
})export default router
  • 安装router:

    • main.ts中添加:
import router from './router'const app = createApp(App)app.use(router)
app.mount('#app')
  • 在App.vue中配置跳转:
<template><div id="app"><router-link to="/login">登录</router-link><router-link to="/main">首页</router-link><router-view></router-view></div>
</template>

vuex集成

  • 安装vuex:
npm install vuex@next
  • 创建store对象:

import { createStore } from 'vuex'const store = createStore({state: () => {return {name: 'Vue Template'}},mutations: {},getters: {},actions: {}
})export default store
  • 安装store:

    • main.ts中添加:
import router from './router'
import store from './store'const app = createApp(App)app.use(router)
app.use(store)
app.mount('#app')
  • 在App.vue中使用:
<h2>{{ $store.state.name }}</h2>
  • 报 $store 无法识别错误,解决方式:

element-plus集成

  • Element Plus,一套为开发者、设计师和产品经理准备的基于 Vue 3.0 的桌面端组件库:
  • 它的使用方式和很多其他的组件库是一样的,所以学会element-plus,其他类似于ant-design-vue、NaiveUI、VantUI都是差不多的;
  • 安装element-plus
npm install element-plus

全局引入

  • 一种引入element-plus的方式是全局引入,代表的含义是所有的组件和插件都会被自动注册:
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'  //新版样式路径发生改变,详见官网import router from './router'
import store from './store'createApp(App).use(router).use(store).use(ElementPlus).mount('#app')

局部引入旧方案 仅供参考,可跳过

  • 在开发中用到某个组件对某个组件进行引入:
<template><div id="app"><router-link to="/login">登录</router-link><router-link to="/main">首页</router-link><router-view></router-view><h2>{{ $store.state.name }}</h2><el-button>默认按钮</el-button><el-button type="primary">主要按钮</el-button><el-button type="success">成功按钮</el-button><el-button type="info">信息按钮</el-button><el-button type="warning">警告按钮</el-button><el-button type="danger">危险按钮</el-button></div>
</template><script lang="ts">
import { defineComponent } from 'vue'import { ElButton } from 'element-plus'export default defineComponent({name: 'App',components: {ElButton}
})
</script><style lang="less">
</style>
  • 以下样式导入有变化(截止2022-3-23),样式路径发生变化
  • 但是我们会发现是没有对应的样式的,引入样式有两种方式(采用全局导入了,下面样式局部导入仅供参考,样式路径发生了变化):
    • 全局引用样式(像之前做的那样);
    • 局部引用样式(通过babel的插件);
  • 1.安装babel的插件:
npm install babel-plugin-import -D
  • 2.配置babel.config.js
module.exports = {plugins: [['import',{libraryName: 'element-plus',customStyleName: (name) => {return `element-plus/lib/theme-chalk/${name}.css`}}]],presets: ['@vue/cli-plugin-babel/preset']
}
  • 导入需要的模块

  • register-element.ts
import { App } from 'vue'import {ElButton,ElCheckbox,ElForm,ElFormItem,ElInput,ElTabPane
} from 'element-plus'const components = [ElButton,ElForm,ElFormItem,ElInput,ElTabPane,ElCheckbox
]export default function (app: App): void {for (const component of components) {app.component(component.name, component)}
}
  • index.ts
import { App } from 'vue'
import registerElement from './register-element'export function globalRegister(app: App): void {app.use(registerElement)
}
  • main.ts
import { createApp } from 'vue'
import App from './App.vue'import { globalRegister } from './global'import router from './router'
import store from './store'const app = createApp(App)app.use(globalRegister)
app.use(router)
app.use(store)
app.mount('#app')

局部引入新方案(推荐)

  • 按需引入需要安装以下:

    • 参考:快速开始 | Element Plus
    • 《vue3中按需引入element-plus组件报错》
  • 安装插件:
npm install -D unplugin-vue-components unplugin-auto-import
  • vue.config.js
const { defineConfig } = require('@vue/cli-service')
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')module.exports = defineConfig({configureWebpack: {plugins: [AutoImport({resolvers: [ElementPlusResolver()]}),Components({resolvers: [ElementPlusResolver()]})]},transpileDependencies: true
})

axios集成

  • 安装axios:
npm install axios

区分不同环境

  • 方式1:

// 根据process.env.NODE_ENV区分
// 开发环境: development
// 生成环境: production
// 测试环境: testlet BASE_URL = ''
const TIME_OUT = 10000if (process.env.NODE_ENV === 'development') {BASE_URL = 'http://123.207.32.32:8000/'
} else if (process.env.NODE_ENV === 'production') {BASE_URL = 'http://coderwhy.org/prod'
} else {BASE_URL = 'http://coderwhy.org/test'
}export { BASE_URL, TIME_OUT }
  • 方式2:

  • 具体参考:模式和环境变量 | Vue CLI

 封装

  • src\service\request\type.ts
import type { AxiosRequestConfig, AxiosResponse } from 'axios'export interface HYRequestInterceptors<T = AxiosResponse> {requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfigrequestInterceptorCatch?: (error: any) => anyresponseInterceptor?: (res: T) => TresponseInterceptorCatch?: (error: any) => any
}export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {interceptors?: HYRequestInterceptors<T>showLoading?: boolean
}
  • src\service\request\index.ts
import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { HYRequestInterceptors, HYRequestConfig } from './type'import { ElLoading } from 'element-plus'
import { ILoadingInstance } from 'element-plus/lib/el-loading/src/loading.type'const DEAFULT_LOADING = trueclass HYRequest {instance: AxiosInstanceinterceptors?: HYRequestInterceptorsshowLoading: booleanloading?: ILoadingInstanceconstructor(config: HYRequestConfig) {// 创建axios实例this.instance = axios.create(config)// 保存基本信息this.showLoading = config.showLoading ?? DEAFULT_LOADINGthis.interceptors = config.interceptors// 使用拦截器// 1.从config中取出的拦截器是对应的实例的拦截器this.instance.interceptors.request.use(this.interceptors?.requestInterceptor,this.interceptors?.requestInterceptorCatch)this.instance.interceptors.response.use(this.interceptors?.responseInterceptor,this.interceptors?.responseInterceptorCatch)// 2.添加所有的实例都有的拦截器this.instance.interceptors.request.use((config) => {console.log('所有的实例都有的拦截器: 请求成功拦截')if (this.showLoading) {this.loading = ElLoading.service({lock: true,text: '正在请求数据....',background: 'rgba(0, 0, 0, 0.5)'})}return config},(err) => {console.log('所有的实例都有的拦截器: 请求失败拦截')return err})this.instance.interceptors.response.use((res) => {console.log('所有的实例都有的拦截器: 响应成功拦截')// 将loading移除this.loading?.close()const data = res.dataif (data.returnCode === '-1001') {console.log('请求失败~, 错误信息')} else {return data}},(err) => {console.log('所有的实例都有的拦截器: 响应失败拦截')// 将loading移除this.loading?.close()// 例子: 判断不同的HttpErrorCode显示不同的错误信息if (err.response.status === 404) {console.log('404的错误~')}return err})}request<T>(config: HYRequestConfig<T>): Promise<T> {return new Promise((resolve, reject) => {// 1.单个请求对请求config的处理if (config.interceptors?.requestInterceptor) {config = config.interceptors.requestInterceptor(config)}// 2.判断是否需要显示loadingif (config.showLoading === false) {this.showLoading = config.showLoading}this.instance.request<any, T>(config).then((res) => {// 1.单个请求对数据的处理if (config.interceptors?.responseInterceptor) {res = config.interceptors.responseInterceptor(res)}// 2.将showLoading设置true, 这样不会影响下一个请求this.showLoading = DEAFULT_LOADING// 3.将结果resolve返回出去resolve(res)}).catch((err) => {// 将showLoading设置true, 这样不会影响下一个请求this.showLoading = DEAFULT_LOADINGreject(err)return err})})}get<T>(config: HYRequestConfig<T>): Promise<T> {return this.request<T>({ ...config, method: 'GET' })}post<T>(config: HYRequestConfig<T>): Promise<T> {return this.request<T>({ ...config, method: 'POST' })}delete<T>(config: HYRequestConfig<T>): Promise<T> {return this.request<T>({ ...config, method: 'DELETE' })}patch<T>(config: HYRequestConfig<T>): Promise<T> {return this.request<T>({ ...config, method: 'PATCH' })}
}export default HYRequest
  • 导出:src\service\index.ts
// service统一出口
import HYRequest from './request'
import { BASE_URL, TIME_OUT } from './request/config'const hyRequest = new HYRequest({baseURL: BASE_URL,timeout: TIME_OUT,interceptors: {requestInterceptor: (config) => {// 携带token的拦截const token = ''if (token) {config.headers.Authorization = `Bearer ${token}`}console.log('请求成功的拦截')return config},requestInterceptorCatch: (err) => {console.log('请求失败的拦截')return err},responseInterceptor: (res) => {console.log('响应成功的拦截')return res},responseInterceptorCatch: (err) => {console.log('响应失败的拦截')return err}}
})export default hyRequest
  • 使用:
import hyRequest from './service'hyRequest.request({url: '/home/multidata',method: 'GET',headers: {},interceptors: {requestInterceptor: (config) => {console.log('单独请求的config')config.headers['token'] = '123'return config},responseInterceptor: (res) => {console.log('单独响应的response')return res}}
})interface DataType {data: anyreturnCode: stringsuccess: boolean
}hyRequest.get<DataType>({url: '/home/multidata',showLoading: false}).then((res) => {console.log(res.data)console.log(res.returnCode)console.log(res.success)})

tsconfig.json

{"compilerOptions": {// 目标代码(ts -> js(es5/6/7))"target": "esnext",// 目标代码需要使用的模块化方案(commonjs require/module.exports/es module import/export)"module": "esnext",// 严格一些严格的检查(any)"strict": true,// 对jsx进行怎么样的处理"jsx": "preserve",// 辅助的导入功能"importHelpers": true,// 按照node的方式去解析模块 import "/index.node""moduleResolution": "node",// 跳过一些库的类型检测 (axios -> 类型/ lodash -> @types/lodash / 其他的第三方)// import { Person } from 'axios'"skipLibCheck": true,// export default/module.exports = {}// es module 和 commonjs"esModuleInterop": true,"allowSyntheticDefaultImports": true,// 要不要生成映射文件(ts -> js)"sourceMap": true,// 文件路径在解析时, 基本url"baseUrl": ".",// 指定具体要解析使用的类型"types": ["webpack-env"],// 路径解析(类似于webpack alias)"paths": {"@/*": ["src/*"],"components/*": ["src/components/*"]},// 可以指定在项目中可以使用哪里库的类型(Proxy/Window/Document)"lib": ["esnext", "dom", "dom.iterable", "scripthost"]},"include": ["src/**/*.ts","src/**/*.tsx","src/**/*.vue","tests/**/*.ts","tests/**/*.tsx"],"exclude": ["node_modules"]
}

样式

npm install normalize.css
  • 创建css 目录

  • index.js
import 'element-plus/dist/index.css'
import 'normalize.css'
import './base.less'
  • main.js:
import './assets/css'

主题颜色

  • 官网参考:主题 | Element Plus
  • 安装scss 
    • 《vue项目安装scss》
npm install node-sass sass-loader style-loader --save
  • 使用scss方式没成功。采用css 变量方式。
  • base.less:
:root {--el-color-primary: green !important;
}

Vue3项目搭建学习笔记相关推荐

  1. 【卷积神经网络环境搭建学习笔记】

    卷积神经网络环境搭建学习笔记 前言 首先,特别感谢B站UP主:肆十二- csdn链接:https://blog.csdn.net/ECHOSON/article/details/117964438 再 ...

  2. Android Studio下载搭建学习笔记01

    Android Studio下载搭建学习笔记01 下载Android Studio 安装Android Studio 进入安装向导 选择安装组件 选择安装位置 选择文件菜单 等待安装 启动并配置And ...

  3. Class4 Linux云上环境搭建学习笔记

    Class4 Linux云上环境搭建学习笔记 Linux的远程管理 为Linux环境安装图形化桌面(Gnome) 学习Linux的基本操作 更新一个官方教程 附阿里云高校学习计划的地址 class4 ...

  4. 目标检测—基于Yolov5的目标检测项目(学习笔记)

    今天学习了炮哥带你学的yolov5入门教程,并成功的训练出了模型,原博客地址: 目标检测-教你利用yolov5训练自己的目标检测模型 本文主要讲述了在Windows10环境下复现此项目的具体过程和遇到 ...

  5. htmlcss实例小项目_HTMLCSS学习笔记(十九)-- 媒体查询

    媒体查询 媒体查询可以让我们根据设备显示器的特性(如视口宽度.屏幕比例.设备方向:横向或纵向)为其设定CSS样式,媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成.媒体查询中可用于检测的媒体 ...

  6. Vue3 文档学习笔记

    vue3学习笔记 setup() 生命周期的与vue2的不同点在:beforeCreated.created都在setup()里进行默认调用,其他的都要写在setup()里面,算做compositio ...

  7. Vue3项目搭建全过程

    目录 一.前言 二.搭建准备 三.搭建项目 四.启动项目 一.前言 在2020年的9月19日,万众期待的Vue3终于发布了正式版,命名为"One Piece". 它也带来了很多新的 ...

  8. vue3 项目搭建以及使用

    一.创建一个普通的vue3项目 创建一个普通的vue3项目 //注意如果之前安装过的话建议先卸载再重新安装 npm uninstall vue-cli -g //yarn global remove ...

  9. 《黑马程序员2023新版黑马程序员大数据入门到实战教程,大数据开发必会的Hadoop、Hive,云平台实战项目》学习笔记总目录

    本文是对<黑马程序员新版大数据入门到实战教程>所有知识点的笔记进行总结分类. 学习视频:黑马程序员新版大数据 学习时总结的学习笔记以及思维导图会在后续更新,请敬请期待. 前言:配置三台虚拟 ...

最新文章

  1. springboot获取URL请求参数的几种方法
  2. Keras情感分析(Sentiment Analysis)实战---自然语言处理技术
  3. python函数递归年龄_Python学习笔记4-递归函数
  4. linux下设置SMTP服务器并用mail命令发送邮件精解
  5. kitti数据集坐标转换
  6. wsimport命令介绍
  7. CCProxy使用 记录
  8. 【论文制图】chemdraw安装与使用
  9. Qt setStyleSheet 透明图片叠加
  10. CoAP协议及开源实现
  11. 基于华视身份证读卡器读取身份证信息的Android demo
  12. docker 创建nacos-server standalone
  13. Liam的操作系统学习历程(一):xv6 homework 9 Barriers
  14. 安装 synaptic on ubuntu 18
  15. 下载美拍视频 python
  16. 二维码符号体系已经到来
  17. Internet Download Manager2022中文版免费下载
  18. 微信小程序监听实时地理位置变化事件接口申请
  19. WEB数据库管理平台kb-dms:数据源权限配置【八】
  20. 一:用MATLAB求传递函数的零点,极点以及增益K

热门文章

  1. Java练习题——超市贴花
  2. iPhone6和iPhone6 Plus的分辨率和像素
  3. 远程登录Linux服务器
  4. 平台联合卖会员、用户拆着挂闲鱼,巨头联名会员卡命宿何方?
  5. Linux服务器EDAC CE memory read error
  6. HTTP上传文件的总结
  7. 双非硕士分享秋招经历:拿到11+5家Offer,去哪儿、商汤体验最差
  8. 【Axure高保真原型】刮奖原型
  9. 光脚丫思考Vue3与实战:第03章 Vue实例
  10. 周经理写给公司 的一封信