文章目录
项目搭建
创建vue项目
一、方式一:Vue CLI
- 基于webpack工具
- 命令:
vue create
二、方式二:create-vue
- 基于vite工具
- 命令:
npm init vue@latest
vue router和pinia都选择no是因为想教大家如何自己手动搭建
创建好项目后在终端输入npm install
安装依赖
目录结构
.vscode文件中recommendations字段为vscode建议你安装的插件,如果你之前没安装这些插件,那么vscode会在右下角弹出弹窗问你要不要安装
public:放资源,最终打包后会放在dist文件夹中。favicon.ico为网站图标
src:源代码
.gitignore:指定提交GitHub时忽略的文件
env.d.ts:.d.ts为类型声明文件
index.html:html模板,入口文件
package.json:记录版本信息
package-lock.json:记录锁定的版本信息
tsconfig.json:(开发环境配置)
{
"extends": "@vue/tsconfig/tsconfig.web.json",// 继承@vue/tsconfig/tsconfig.web.json配置文件,主要是框架不想让你看那么多配置内容
// 其实@vue/tsconfig下不仅有tsconfig.web.json,还有tsconfig.node.json,tsconfig.node.json主要运用于ssr,ssr运行在node上
"include": ["src/**/*", "src/**/*.vue", "env.d.ts"],// 哪些文件需要编译
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]// 用于vscode编写代码提示
},
"noImplicitAny": false,// 开启隐式的any
},
"references": [// 引入文件
// 这里又引入了一个配置文件,为什么不把配置写在一个配置文件里?
// 1. vite生成tsconfig.json后,不建议我们手动修改tsconfig.json,但如果在项目中有些单独的配置,建议在tsconfig.config.json进行修改
// 最终tsconfig.config.json会被合并到tsconfig.json,因为tsc和vscode最终识别的都是tsconfig.json
// 2. 如果项目需要运行在node上,需要在tsconfig.config.json配置:"extends": "@vue/tsconfig/tsconfig.node.json"
// tsconfig.config.json配置的include都是基于vite环境的配置,vite代码的打包和编译都是基于node的,
// tsconfig.json的include配置里并不包含vite.config.ts文件,vite的配置也需要打包呀
{
"path": "./tsconfig.config.json"
}
]
}
tsconfig.config.json:(为打包所做的配置)
{
"extends": "@vue/tsconfig/tsconfig.node.json",
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*"],// 基于vite环境的配置,vite代码的打包和编译都是基于node的,
"compilerOptions": {
"composite": true,// tsconfig.config.json最终会合并到tsconfig.json
"types": ["node"]//在node环境进行编译
}
}
vite.config.ts:配置vite
export default defineConfig({
plugins: [vue()],// 配置插件
resolve: {
// resolve用于配置路径
alias: {
// alias用于配置别名,主要用于vite打包时,将@转为./src
// @指向./src,默认使用es6语法,es6使用的是es module,所以用的import
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
webpack的配置文件为vue.config.js,最终会把vue cli中的webpack和vue.config.js合在一起
扫描二维码关注公众号,回复: 17505159 查看本文章![]()
main.ts中引入.css文件没有报错是因为在env.d.ts中引入了<reference types="vite/client" />
,vite/client
声明了.css文件。现在我们想声明.vue文件为组件,在env.d.ts中配置:
// 声明.vue文件为组件
declare module '*.vue' {
import {
DefineComponent } from 'vue'// 为什么要使用DefineComponent,可以看看视频
const component: DefineComponent
export default component
}
项目代码规范
editorconfig文件配置
EditorConfig有助于为不同IDE编辑器上处理同一项目的多个开发人员维护一致的编码风格。比如你们团队有人喜欢用webstorm开发,webstorm采用gbk编码,有人喜欢用vscode开发,vscode采用utf-8编码,还有的人喜欢用idea开发,idea采用utf-16编码,那么某个人打开代码的时候就会出现乱码,为了解决这一问题,可以在项目中创建.editorConfig文件,内容如下:
# http://editorconfig.org
root = 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# 去除尾部空格,如果前面为所有文件设置了trim_trailing_whitespace = true,这里可以设为false
配置好了之后,vscode需要安装EditorConfig for VS Code插件
现在使用prettier和eslint来配置也行,而且如果你们使用的是同一个ide编辑器的话,不需要配置该文件
prettier格式化配置
Prettier是一款强大的代码格式化工具,支持 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等语言,基本上前端能用到的文件格式它都可以搞定,是当下最流行的代码格式化工具。
- 安装:
npm install prettier -D
- 配置.prettierrc文件(配置.prettierrc.json也行,但文件格式得为json格式):
{
"useTabs": false,// 使用tab缩进还是空格缩进,选择false;
"tabWidth": 2,// tab是空格的情况下,是几个空格,选择2个;
"printWidth": 80,// 当行字符的长度,推荐80,也有人喜欢100或者120;
"singleQuote": true,// 使用单引号还是双引号,选择true,使用单引号;
"trailingComma": "none",// 在多行输入的尾逗号是否添加,设置为 `none`,比如对象类型的最后一个属性后面是否加一个,;
"semi": false// 语句末尾是否要加分号,默认值true,选择false表示不加;
}
- 如果希望某些文件不被prettier格式化,可以创建.prettierignore忽略文件
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
- VSCode安装prettier的插件,并在VSCode中的配置
- settings =>format on save => 勾选上
- settings => editor default format => 选择 prettier
在代码中保存代码即可生效
- 如果不安装插件,可以在在package.json中配置一个scripts:
"prettier": "prettier --write ."
之后在终端执行npm run prettier
就可以格式化文件了
eslint代码检测配置
eslint用于对不规范的代码进行提示
- 在前面创建项目的时候,我们就选择了ESLint,所以Vue会默认帮助我们配置需要的ESLint环境。
- VSCode需要安装ESLint插件:
- 解决eslint和prettier冲突的问题:
安装插件:(vue在创建项目时,如果选择prettier,那么这两个插件会自动安装)
npm install eslint-plugin-prettier eslint-config-prettier -D
在.eslint.csj文件中添加prettier插件,之后eslint会读取prettier的配置,双方保持一致:
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended",
"@vue/prettier",
"@vue/prettier/@typescript-eslint",
'plugin:prettier/recommended'// 添加prettier插件
],
- 如果eslint不检测react,需要在.eslint.csj中进行如下配置:
"eslint.lintTask.enable": true,
"eslint.alwaysShowStatus": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
如果你不希望eslint出现某个警告,可以在.eslint.csj文件中进行规则配置
css样式的重置
对默认CSS样式进行重置:
- normalize.css
(1)安装:在终端输入npm install normalize.css
(2)在main.ts中导入:import "normalize.css"
- reset.css
(1)新建src/assets/css/reset.less,代码如下:
blockquote, body, button, dd, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, hr, input, legend, li, ol, p, pre, td, textarea, th, ul {
// color: @mainColor;
padding: 0;
margin: 0;
}
a {
color: #333;
text-decoration: none;
}
img {
vertical-align: top;
}
(2)在index.less中先引入reset.less,再引入你写的样式
(3)再在main.ts中导入:import "./assets/css/index.less"
(5)vite本身不支持打包less,需要安装less才能打包:npm install less -D
router路由的配置
一、安装:npm install vue-router
因为在生产环境也依赖vue-router,所以安装的时候不用写-D
二、在index.ts中做如下配置:
/:pathMatch(.*)
:用于匹配所有可能的路径,起到兜底的作用,主要是为了确保所有未匹配的路径都会重定向到 /error/404,以便给用户返回一个统一的 404 错误页面。
三、挂载:
import router from "./router"
const app = createApp(App)
app.use(router)
四、【小技巧】使用snippet-generator生成代码块:
在线链接
使用教程
pinia状态管理配置
一、安装:npm install pinia
二、创建store/index.ts,代码如下:
import {
createPinia} from "pinia"
const pinia = createPinia()
export default pinia
三、挂载:
import pinia from "./pinia"
const app = createApp(App)
app.use(pinia)
四、定义:
import {
defineStore } from 'pinia'
const useCounterStore = defineStore('counter', {
state: () => ({
// 返回一个对象
counter: 100
}),
getters: {
doubleCounter(state) {
return state.counter * 2
}
},
actions: {
changeCounterAction(newCounter: number) {
this.counter = newCounter
}
}
})
export default useCounterStore
五、使用:
<template>
<div class="main">
<h2>main: {
{ counterStore.counter }}-{
{ counterStore.doubleCounter }}</h2>
<button @click="changeCounter">修改counter</button>
</div>
</template>
<script setup lang="ts">
import useCounterStore from '@/store/counter'
const counterStore = useCounterStore()
function changeCounter() {
counterStore.changeCounterAction(999)
}
</script>
<style lang="less" scoped>
.main {
color: red;
}
</style>
axios网络请求的配置
一、安装:npm install axios
二、在src/service/request/request.ts中进行axios二次封装:
import axios from 'axios'
import type {
AxiosInstance } from 'axios'
import type {
HYRequestConfig } from './type'
// 拦截器: 蒙版Loading/token/修改配置
/**
* 两个难点:
* 1.拦截器进行精细控制
* > 全局拦截器
* > 实例拦截器
* > 单次请求拦截器
*
* 2.响应结果的类型处理(泛型)
*/
class HYRequest {
instance: AxiosInstance
// request实例 => axios的实例
constructor(config: HYRequestConfig) {
this.instance = axios.create(config)
// 每个instance实例都添加拦截器
this.instance.interceptors.request.use(
(config) => {
// loading/token
return config
},
(err) => {
return err
}
)
this.instance.interceptors.response.use(
(res) => {
return res.data
},
(err) => {
return err
}
)
// 针对特定的hyRequest实例添加拦截器
this.instance.interceptors.request.use(
config.interceptors?.requestSuccessFn,
config.interceptors?.requestFailureFn
)
this.instance.interceptors.response.use(
config.interceptors?.responseSuccessFn,
config.interceptors?.responseFailureFn
)
}
// 封装网络请求的方法
// T => IHomeData
request<T = any>(config: HYRequestConfig<T>) {
// 单次请求的成功拦截处理
if (config.interceptors?.requestSuccessFn) {
config = config.interceptors.requestSuccessFn(config)
}
// 返回Promise
return new Promise<T>((resolve, reject) => {
this.instance
.request<any, T>(config)
.then((res) => {
// 单词响应的成功拦截处理
if (config.interceptors?.responseSuccessFn) {
res = config.interceptors.responseSuccessFn(res)
}
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
get<T = any>(config: HYRequestConfig<T>) {
return this.request({
...config, method: 'GET' })
}
post<T = any>(config: HYRequestConfig<T>) {
return this.request({
...config, method: 'POST' })
}
delete<T = any>(config: HYRequestConfig<T>) {
return this.request({
...config, method: 'DELETE' })
}
patch<T = any>(config: HYRequestConfig<T>) {
return this.request({
...config, method: 'PATCH' })
}
}
export default HYRequest
在src/service/request/index.ts代码如下:
import HYRequest from './request/request'
import {
API_BASE_URL, TIME_OUT } from './request/config'
import localCache from '@/utils/cache'
const hyRequest = new HYRequest({
baseURL: API_BASE_URL,
timeout: TIME_OUT,
interceptorHooks: {
requestInterceptor: (config) => {
const token = localCache.getCache('token')
if (token) {
config.headers.Authorization = `Bearer ${
token}`
}
return config
},
requestInterceptorCatch: (err) => {
return err
},
responseInterceptor: (res) => {
return res.data
},
responseInterceptorCatch: (err) => {
return err
}
}
})
export default hyRequest
四、在Main.vue中使用:
<script>
import hyRequest from "@/service"
hyRequest.get({
url:"/home/multidata"}).then((res) => {
console.log(res)
})
</script>
区分开发和生产环境
Vite提供了环境变量import.meta.env
import.meta.env.MODE: {string}
应用运行的模式:开发、生产import.meta.env.PROD: {boolean}
应用是否运行在生产环境。import.meta.env.DEV: {boolean}
应用是否运行在开发环境(永远与import.meta.env.PROD
相反)。import.meta.env.SSR: {boolean}
应用是否运行在server上。
有些变量/标识符在开发环境和生产环境下是不一样的,比如baseUrl="服务器地址"
,由于Vite会使用.env
从环境目录中的下列文件加载额外的环境变量
所以可以在项目中创建.env.production
、.env.development
文件用以存放不同环境的baseUrl
由于以VITE_
为前缀的变量会被挂载到import.meta.env
上,所以之后可以直接使用import.meta.env.VITE_BASE_URL
获得各环境的base URL。此外.local文件在git提交代码的时候,不会被提交,这是因为在.gitignore
配置了:
.env.local
.env.*.local
npm run build
:打包
npm run preview
:对打包的东西进行预览
element-plus全局引入
安装:npm install element-plus --save
导入:
- 全局引入:在main.ts中引入并挂载:
import ElementPlus from "element-plus"
import "element-plus/dist/index.css"
const app = createApp(App)
app.use(ElementPlus)
然后直接使用即可,但是不推荐这种方式,因为他打包体积大
如果使用了Volar,可以在tsconfig.json中通过compilerOptions.type指定全局组件类型,这样在写代码的时候,会提示你组件有哪些属性。(前提是进行了全局引入)
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["element-plus/global"]
}
}
- 按需引入:在main.ts中引入要使用的组件:
import {
ElButton} from "element-plus"
const app = createApp(App)
app.component(ElButton.name,ElButton)
如果某个组件只在某个vue里使用,那么可以做局部引用,在vue中引入要使用的组件:
import {
ElButton} from "element-plus"
- 使用插件自动引入:
安装unplugin-vue-components 和 unplugin-auto-import这两款插件:npm install -D unplugin-vue-components unplugin-auto-import
,然后把下列代码插入到你的Vite或Webpack的配置文件中就可以直接使用组件了:
// vite.config.ts
import {
defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import {
ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
// webpack.config.js或vue.config.js
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const {
ElementPlusResolver } = require('unplugin-vue-components/resolvers')
module.exports = {
// ...
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}
各模块开发
登陆模块
一、设置界面铺满整个屏幕:
.app{
width: 100vw;
height: 100vh;
}
二、