环境准备
- Vscode/HBuilder等任何一种前端开发工具
- node.js&npm本地开发环境
- 源代码管理:Git
技术栈
项目构建
创建项目
npm create vite
依次运行最后三行出现,成功启动项目
在浏览器输入 http://localhost:5173/ 可以显示页面
src别名的配置
在开发项目的时候文件与文件关系可能很复杂,因此我们需要给src文件夹配置一个别名!!!
vue
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": path.resolve("./src") // 相对路径别名配置,使用 @ 代替 src
}
}
})
TypeScript 编译配置
vue
{
"compilerOptions": {
"baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
"paths": { //路径映射,相对于baseUrl
"@/*": ["src/*"]
}
}
}
环境变量的配置
项目开发过程中,至少会经历开发环境、测试环境和生产环境(即正式环境)三个阶段。不同阶段请求的状态(如接口地址等)不尽相同,若手动切换接口地址是相当繁琐且易出错的。于是环境变量配置的需求就应运而生,我们只需做简单的配置,把环境状态切换的工作交给代码。
:::info
- 开发环境(development)
顾名思义,开发使用的环境,每位开发人员在自己的dev分支上干活,开发到一定程度,同事会合并代码,进行联调。
- 测试环境(testing)
测试同事干活的环境啦,一般会由测试同事自己来部署,然后在此环境进行测试
- 生产环境(production)
生产环境是指正式提供对外服务的,一般会关掉错误报告,打开错误日志。(正式提供给客户使用的环境。)
:::
注意:
一般情况下,一个环境对应一台服务器,也有的公司开发与测试环境是一台服务器!!!项目根目录分别添加开发、生产和测试环境的文件!
vue
.env.development
.env.production
.env.test
文件内容
vue
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = 'xxxx'
VITE_APP_BASE_API = '/dev-api'
NODE_ENV = 'production'
VITE_APP_TITLE = 'xxxx'
VITE_APP_BASE_API = '/prod-api'
NODE_ENV = 'test'
VITE_APP_TITLE = 'xxxx'
VITE_APP_BASE_API = '/test-api'
配置运行命令:package.json
vue
"scripts": {
"dev": "vite --open",
"build:test": "vue-tsc && vite build --mode test",
"build:pro": "vue-tsc && vite build --mode production",
"preview": "vite preview"
},
通过
**import.meta.env**
获取环境变量
安装 Element Plus 组件库
npm install element-plus
引入 Element Plus 组件库并使用
vue
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
测试安装结果
vue
<template>
<div>
<h1>App</h1>
<el-button type="primary">button</el-button>
</div>
</template>
按钮正常显示,说明安装成功
安装 Vue Router 路由管理库
npm install vue-router
在项目的 src 目录下新建一个 views 目录,然后在 views 目录下新建两个页面(login/index.vue; dashboard/index.vue),用于路由跳转。
在项目的 src 目录下新建一个 router 目录,然后在 router 目录下新建一个 index.js 文件,该文件会作为 Vue Router 的入口文件,该文件内容如下
vue
<!-- Vue Router 的入口文件 -->
import {createRouter, createWebHistory} from "vue-router";
const router = new createRouter({
history: createWebHistory(),
routes: [
{
path: "/login",
name: "Login",
component: () => import("../views/login/index.vue"),
},
{
path: "/dashboard",
name: "Dashboard",
component: () => import("../views/dashboard/index.vue"),
},
]
})
export default router
vue
// src/main.js
// ...
import router from './router' // 新增
app.use(router) // 新增:使用 Vue Router
// ...
修改 App.vue 文件,添加路由跳转
vue
<template>
<div class="app-container">
<ul>
<!-- router-link 是用来实现路由跳转 -->
<li><router-link to="/dashboard">首页</router-link></li>
<li><router-link to="/login">登录</router-link></li>
</ul>
<!-- router-view 是用来显示路由对应的内容 -->
<router-view />
</div>
</template>
安装 Pinia 状态管理库
npm install pinia
在项目的 src 目录下新建一个 store 目录,然后在 store 目录下新建一个 index.ts 文件,该文件会作为 Pinia 的入口文件
vue
import {createPinia} from 'pinia'
const pinia = createPinia()
export default pinia
在 src/main.ts 文件中引入 Pinia,并使用 Pinia
vue
// src/main.js
// ...
import pinia from './store' // 新增
app.use(router) // 新增:使用 Pinia
// ...
在 src/store 目录下创建一个 modules 目录,然后在 modules 目录下创建一个 user
状态管理对象,用于管理整个项目的用户登录状态
vue
// src/store/modules/user.js
import {defineStore} from 'pinia'
import {ref} from 'vue'
const useUserStore = defineStore('user', () => {
const userInfo = ref({})
const loginStatus = ref(false)
const token = ref('')
/**
* 登录
*/
function handleLogin() {
return new Promise((resolve, reject) => {
// 当随机数大于0.8时,成功登录
if(Math.random() > 0.8){
loginStatus.value = true
token.value = String(new Date().getTime())
userInfo.value = {
name: 'admin',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80',
}
resolve('登录成功')
}else {
reject('登录失败')
}
})
}
/**
* 退出登录
*/
function handleLogout() {
return new Promise((resolve) => {
loginStatus.value = false
token.value = ''
userInfo.value = {}
resolve()
})
}
return {
userInfo,
loginStatus,
token,
handleLogin,
handleLogout
}
})
export default useUserStore
安装 Sass CSS 预处理器
npm install sass -D
在项目的 src 目录下新建一个 styles
目录,然后在 styles 目录下新建一个 variables.scss
文件,该文件存放全局的 Sass 变量
vue
$success: #48C78E;
$danger: #F28482;
首页测试 Sass 变量,在 src/views/dashboard/index.vue 文件中修改如下
vue
<template>
<h1 class="success">这是一个成功样式</h1>
<h2 class="danger">这是一个告警样式</h2>
</template>
<style scoped lang="scss">
.success{
color:$success;
}
.danger{
color: $danger;
}
</style>
在 vite.config.js 文件中引入Undefined variable.,才能使用 Sass 变量
vue
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
css: {
// CSS 预处理器
preprocessorOptions: {
// 定义全局 SCSS 变量
scss: {
javascriptEnabled: true,
additionalData: "@use '/src/styles/variables.scss' as *;",
},
},
},
})
安装 VueUse 工具库
npm i @vueuse/core
在 src/views/dashboard/index.vue 文件中,使用 VueUse 的 useMouse
方法,获取当前鼠标实时位置
vue
<template>
<h1 class="success">这是一个成功样式</h1>
<h2 class="danger">这是一个告警样式</h2>
<p>当前鼠标位置:X:{{ x }}、Y:{{ y }}</p>
</template>
<script setup>
import {useMouse} from '@vueuse/core'
const {x,y} = useMouse()
</script>
<style scoped lang="scss">
.success{
color:$success;
}
.danger{
color: $danger;
}
</style>
安装 Axios 网络请求库(未完成)
npm install axios
在 src 目录下新建一个 utils 目录,然后在 utils 目录下新建一个 request.ts
文件,在该文件中,可以在发起请求前向请求头中添加一些请求头等信息
对axios二次封装
目的:
- 使用请求拦截器,可以在请求拦截器中处理一些业务(开始进度条、请求头携带公共参数)
- 使用响应拦截器,可以在响应拦截器中处理一些业务(进度条结束、简化服务器返回的数据、处理http网络错误)
在根目录下创建utils/request.ts
vue
import axios from "axios";
import { ElMessage } from "element-plus";
//创建axios实例
let request = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 5000
})
//请求拦截器
request.interceptors.request.use(config => {
return config;
});
//响应拦截器
request.interceptors.response.use((response) => {
return response.data;
}, (error) => {
//处理网络错误
let msg = '';
let status = error.response.status;
switch (status) {
case 401:
msg = "token过期";
break;
case 403:
msg = '无权访问';
break;
case 404:
msg = "请求地址错误";
break;
case 500:
msg = "服务器出现问题";
break;
default:
msg = "无网络";
}
ElMessage({
type: 'error',
message: msg
})
return Promise.reject(error);
});
export default request;
安装 Echarts 图表库
npm install echarts
在 src/views/dashboard/index.vue 文件中,使用 Echarts 的 init
方法,初始化一个图表
vue
<script setup>
import * as echarts from 'echarts';
import {onMounted, ref} from "vue";
const chartRef = ref(null)
let echartClient = null
onMounted(() => {
initChart()
})
function initChart() {
echartClient = echarts.init(chartRef.value)
echartClient.setOption({
tooltip: {},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
})
}
</script>
<template>
<div class="chart-box" ref="chartRef" ></div>
</template>
<style scoped lang="scss">
.chart-box{
width: 600px;
height: 400px;
}
</style>
页面上可以看到一个柱状图,表示 Echarts 工具库已经正常工作了
安装 Eslint 代码检查工具
npm init @eslint/config
新增.eslintignore忽略文件
vue
dist
node_modules
package.json新增两个运行脚本
vue
"scripts": {
"lint": "eslint src",
"fix": "eslint src --fix",
}
安装 Prettier 代码格式化工具
npm install -D eslint-plugin-prettier prettier eslint-config-prettier
新增.prettierrc.json添加规则
vue
{
"singleQuote": true,
"semi": false,
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "ignore",
"endOfLine": "auto",
"trailingComma": "all",
"tabWidth": 2
}
新增.prettierignore忽略文件
vue
/dist/*
/html/*
.local
/node_modules/**
**/*.svg
**/*.sh
/public/*
安装 stylelint css代码格式化工具
npm add sass sass-loader stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order stylelint-config-standard-scss -D
新增.stylelintrc.cjs配置文件
vue
// @see https://stylelint.bootcss.com/
module.exports = {
extends: [
'stylelint-config-standard', // 配置stylelint拓展插件
'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
'stylelint-config-standard-scss', // 配置stylelint scss插件
'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
'stylelint-config-prettier', // 配置stylelint和prettier兼容
],
overrides: [
{
files: ['**/*.(scss|css|vue|html)'],
customSyntax: 'postcss-scss',
},
{
files: ['**/*.(html|vue)'],
customSyntax: 'postcss-html',
},
],
ignoreFiles: [
'**/*.js',
'**/*.jsx',
'**/*.tsx',
'**/*.ts',
'**/*.json',
'**/*.md',
'**/*.yaml',
],
/**
* null => 关闭该规则
* always => 必须
*/
rules: {
'value-keyword-case': null, // 在 css 中使用 v-bind,不报错
'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
'no-empty-source': null, // 关闭禁止空源码
'selector-class-pattern': null, // 关闭强制选择器类名的格式
'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符
'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box
'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask
'selector-pseudo-class-no-unknown': [
// 不允许未知的选择器
true,
{
ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到
},
],
},
}
新增.stylelintignore忽略文件
vue
/node_modules/*
/dist/*
/html/*
/public/*
配置统一的prettier来格式化js和css,html代码
vue
"scripts": {
"dev": "vite --open",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"lint": "eslint src",
"fix": "eslint src --fix",
"format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",
"lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix",
"lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix"
},
配置 Element Plus 按需导入
npm install -D unplugin-vue-components unplugin-auto-import
配置vite.config.ts
vue
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import path from 'path'
export default defineConfig({
plugins: [
vue(),
AutoImport({
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ['vue', 'vue-router', '@vueuse/core'],
// 自动导入 Element Plus 相关函数
resolvers: [ElementPlusResolver()],
eslintrc: {
enabled: true, // 解决 Eslint 提示 no-undef 错误
},
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
'@': path.resolve('./src'), // 相对路径别名配置,使用 @ 代替 src
},
},
css: {
// CSS 预处理器
preprocessorOptions: {
// 定义全局 SCSS 变量
scss: {
javascriptEnabled: true,
additionalData: "@use '/src/styles/variables.scss' as *;",
},
},
},
})
删除 src/main.js
文件中之前引入的 Element Plus 的代码,所有与 Element Plus 相关的代码都被自动导入了,无需再手动引入。
配置 Echarts 按需导入
在 src/utils
文件夹下创建 echarts.ts
文件,把需要用到的图表组件导入到该文件中,在需要使用 Echarts 的地方直接导入该文件,这样就可以按需导入 Echarts 图表库了
vue
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from "echarts/core";
// 引入柱状图图表,图表后缀都为 Chart
import { BarChart } from "echarts/charts";
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
} from "echarts/components";
// 标签自动布局、全局过渡动画等特性
import { LabelLayout, UniversalTransition } from "echarts/features";
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from "echarts/renderers";
// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
LabelLayout,
UniversalTransition,
CanvasRenderer,
]);
export default echarts;
修改 src/views/dashboard/index.vue
文件,引入 src/utils/echarts.ts
文件,这样就可以按需导入 Echarts 图表库了
vue
// import * as echarts from "echarts"; // 删除
import echarts from "@/utils/echarts"; // 新增
整理项目结构
vue
<template>
<div>
<h1>App</h1>
</div>
</template>
删除 src/style.css
文件
删除 src/main.js
中引入的 style.css
文件
使用 Git 管理源代码
bash
#Git仓库初始化
git init
#添加所有文件到版本库
git add .
#提交所有文件到版本库
git commit -m "feat: 项目初始化完成"
#新建 dev 分支,并切换到 dev 分支
git checkout -b dev