# qinghe-vue-pro-element
**Repository Path**: unvue/qinghe-vue-pro-element
## Basic Information
- **Project Name**: qinghe-vue-pro-element
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-06-11
- **Last Updated**: 2025-06-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 创建搭建
## 创建项目
怎么选择工具,我这里使用的是npm,使用yarn等工具都是可以的,vite官网地址:https://vitejs.cn/vite6-cn/guide/
```shell
E:\zbcode>npm create vite@latest
> npx
> create-vite
|
o Project name:
| qinghe-vue-pro-web
|
o Select a framework:
| Vue
|
o Select a variant:
| JavaScript
|
o Scaffolding project in E:\zbcode\qinghe-vue-pro-web...
|
— Done. Now run:
cd qinghe-vue-pro-web
npm install
npm run dev
```
## 项目结构
### 资源目录
在vite项目中,有两个资源目录,一个是`public`,一个是`src/assets`,都可以存放资源,如:图片、css、js等。两者的区别如下:
1. `public`下的资源,不需要经过`vite`处理,直接可以访问;`assets`下的资源`vite`会处理,压缩、编码之类的处理,进行优化。
### 源码目录
`src` 是源码目录,这里面有资源、组件、页面,当然后期还要我们自己创建一些目录,比如:路由、页面、api、工具类等。
- `src/assets` 资源
- `src/components` 组件
### index.html文件
整个程序的入口文件。因为默认的程序,都是单页面应用(SPA)。就这一个入口文件就够了。后期有机会了,给大奖讲解下多页面应用(MPA)。
这个是index.html源码
```html
Vite + Vue
```
在html中,可以看到,有一个id为`app`的`div`;页面还加了js模块,模块路径是`/src/main.js`。
```html
```
这个是`/src/main.js`源码。
对Vue了解的同学,看到这里,基本就知道是干啥的了。
```javascript
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
createApp(App).mount('#app')
```
1. 导入创建`createApp`函数,用于创建Vue 应用实例。
2. 引用样式表,可以删了,没啥用,后面要自己写。
3. 引用了一个`App`的自定义组件。
4. 将`App`组件挂载到`id`为`app`的元素上(就是上面提到过得div)。
### App.vue
打开这个文件,你会发现熟悉的代码。
```html
```
这是仪表标准`Vue组件`,`template`中是该组件的模板,`script`中是数据和逻辑,`style`是样式,在项目启动后,打开的页面就是这个页面。
这个页面中,还引用了`HelloWorld`组件,这个组件,是写在components包里的,后期我们写的组件相关vue文件,全部要发到这个包。
项目启动后,打开样子如下:

上半部分是`App.vue`组件
下半部分是`App.vue`组件中引用的`HelloWorld.vue`组件。
前面我们介绍了public和assets的区别,刚好这里就有个案例:
源码:
```html
```
编译后:
```html
```
观察src,的内容,明显可以看出区别,一个被vite处理了,一个是原生不动的路径。
**经过这么几步,我们就了解到,整个项目的目录结构,项目是怎么从`html`->`js模块`->`vue创建应用`->`组件应用`的全部流程。**
## 开发工具
我只用宇宙最强工具`WebStorm`。别问为啥,应为我爱,谁能挡住爱。也推荐大家用,用过的人都说比`VSCode`好用、简单。
使用`WebStorm`打开你刚才创建的项目,如下图:

## 项目启动
```shell
PS E:\zbcode\qinghe-vue-pro-web> vite dev
VITE v6.3.4 ready in 327 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
```
很多同学拿到别人的项目,不知道怎么启动,很简单,拿到项目后,找到`package.json`,里面有一段是`scripts`,里面就放着启动的秘诀。如下:
```json
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
}
```
```shell
# 启动
vite dev
# 构建
vite build
# 预览
vite preview
```
如果不是用vite创建的项目,大概率启动都是
```shell
# 启动
npm run dev
# 构建
npm run build
# 预览
npm run preview
```
具体怎么启动,看项目是用那个工具创建,目前最多的两种就是npm和vite。命令就看`packages.json`文件的key。
## 访问项目
启动后,会给访问地址,如上面启动后,给出的地址是: http://localhost:5173/ ,这个也是可以在配置文件中配置的。
能出现以下页面,表示项目启动成功。

# 项目初始化
上面创建的项目只是vite给的一个模板,具体项目由那些目录组成,都是什么作用,都是架构师考虑的,经典目录结构如下:
```
qighe-vue-pro-web
├─public(公共文件)
├─src
│ ├─App.vue (入口组件)
│ ├─main.js (入口js)
│ │
│ ├─api(所有接口相关)
│ ├─assets(静态资源)
│ ├─components(组件)
│ ├─layouts(布局)
│ ├─router(路由)
│ ├─stores(状态商店)
│ ├─utils(工具库)
│ └─views(视图)
│
└─ vite.config.ts(vite 配置)
```
上面的目录,我们目前还用不到,但是先创建了,后面用到了,我们在讲解。
## vite配置
### 服务器选项
```json
{
server: {
port: 3000, // 端口
host: '0.0.0.0', // 监听ip
open: true, //开发服务器启动时,自动在浏览器中打开应用程序
proxy: { // 代理
// 带选项写法:
// 前端地址:http://127.0.0.1:3000/api/bar
// 后端地址:-> http://127.0.0.1:9900/bar
"/api/v1": {
target: 'http://127.0.0.1:9900', // 目标服务
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/v1/, ''),
}
}
}
}
```
以上配置作用:
1. 项目启动端口为 3000
2. 监听你本地所有网卡ip,默认只有localhost
3. 项目启动后,就会自动打开浏览器,访问项目
4. 当前端访问地址为"/api/v1"开头的时候,代理服务会将请求转发到http://127.0.0.1:9900的后端服务,并使用空字符串替换掉/api/v1。
## 清理项目
创建项目后,其实很多东西都是不需要的,在这里,我们就清理下。
## main.js
1. 删除样式引用,同时删除`/src/style.css`,如下:
```javascript
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
```
## 清理资源
1. 删除`/src/assets/vue.svg`文件
2. 删除`public/vite.svg`文件
## App.vue
1. 清理无用代码,同时删除`src/components/HelloWorld.vue`文件,如下即可:
```html
```
# UI框架
我本意是想做一个全套课程,使用ElementUI、AntDesignVue、NaiveUI三种流行的前端框架来做,因为思想基本一样,知识框架和组件替换的问题。
但是因为时间原因,先使用ElementUI来做一次,后期有时间了,给大家在补上。
- ElementUI:[官网](https://element-plus.org/zh-CN/)
- AntDesignVue: [官网](https://www.antdv.com/components/overview-cn/)
- NaiveUI: [官网](https://www.naiveui.com/zh-CN/os-theme)
## 安装ElementUI
安装前,请大家最好阅读下官网的兼容性提示。如下:

```shell
# 安装ElementUI
npm install element-plus --save
```
### 完整引入
`main.js`
```javascript
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')
```
`App.vue`
```html
Hello ElementUI
```
注意:``就是`element-ui`的按钮用法。
效果如下:

如上图,说明element-ui已经安装好,并且可以正常使用。
### 按需导入
你需要使用额外的插件来导入要使用的组件。
### 自动导入(推荐)
首先你需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件
```shell
npm install -D unplugin-vue-components unplugin-auto-import
```
然后把下列代码插入到你的 `Vite` 的配置文件中
vite.config.ts
```javascript
...
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vite.dev/config/
export default defineConfig({
plugins: [
...
AutoImport({
imports: ["vue"], // vue函数自动导入
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
...
})
```
**注意:请删除完整引入的代码。**
### 全局配置
上面我们讲过,从`html`->`js模块`->`vue创建应用`->`组件应用`的全部流程。从这个流程来理解,app.vue是我们进入vue世界的第一个组件。所以,全局配置就放到这里就ok了。
`App.vue`
```html
切换
```
上面这个例子知识介绍,全局配置组件`el-config-provider`的用法,这里主要是做了一个国际化语言切换,可以看到表格、分页的相关语言,根据切换可以改变。


我们发现,凡事想要用到全局配置的组件,必须写在`el-config-provider`组件内部。所以,大家思考下,是不是整个项目如果要使用这个全局配置,也要写在这里?
# 布局组件
好了,到现在我们了解到了vue项目搭建过程,执行过程,也简单的配置了vite,了解了全局配置组件。接下来,我们就要开始正式写项目了。在写项目前,我们要知道项目大概长什么样子,怎么布局的吧?
好,我们按照国际惯例,实现1个常用后台布局就行了,如下:

要实现这么个布局,以前确实有点难度,但是好消息是,现在的ui组件,基本都实现了容器组件,就是为了方便布局,在Element Plus里,就实现了。容器组件包含了一下几个:
1. :外层容器。 当子元素中包含 或 时,全部子元素会垂直上下排列, 否则会水平左右排列。
2. :顶栏容器。
3. :侧边栏容器。
4. :主要区域容器。
5. :底栏容器。
## less安装
开发页面,离不开css,但是直接写css不方便,所以我们用less。你可以理解less对css进行了扩展。刚好vite还支持,咱们只需要安装下less就行了。
```shell
npm install -D less
```
### 配置
`vite.config.js`
将@视为源码根目录
```javascript
...
import path from 'path'
export default defineConfig({
...
resolve: {
alias: {
'@': path.resolve(__dirname, './src'), // 将@视为源码根目录
}
},
...
})
```
## Tailwind
`Tailwind` 是一个css框架,它内置了很多样式工具,可以直接用来写常见样式。
```shell
# 安装依赖包
npm install -D tailwindcss@3 postcss autoprefixer
# 初始化tailwindcss,并生成配置文件 tailwind.config.js
npx tailwindcss init
```
### 配置
`postcss.config.cjs`
添加该文件,注意,vite6这里必须是`.cjs`。否则报错,如果报错,也可以尝试改为`.cjs`
```json
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
```
`tailwind.config.js`
```json
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html","./src/**/*.{vue,js}"],
theme: {
extend: {},
},
plugins: [],
}
```
### 使用
将`Tailwind`引入到全局样式表中。
`src/style/index.less`
```less
@tailwind base;
@tailwind components;
@tailwind utilities;
```
这是Tailwind的基础样式,可以初始化项目的样式。比如:`body`等元素的初始化。
### 引入
并将全局样式表在`main.js`中引入
```javascript
import App from './App.vue'
import "./style/index.less" // 引入全局样式
const app = createApp(App)
app.mount('#app')
```
## Layout组件
布局可以参考ElementUI[官网布局](https://element-plus.org/zh-CN/component/container.html) ,有很多布局,符合我们目标的布局如下:

### 代码结构

### index.vue
`src/layout/index.vue`
项目的布局组件。
```vue
Header
Main
```
在EleumetUI布局的基础上,我们添加了自己的样式,来实现我们想要的效果。
1. 首先,引入了`variables.less`,这里定义了我们整个项目中的样式参数,如:侧边栏背景色、侧边栏宽度等。
2. 定义`.layout`类样式,这个样式是空的,就是个父样式,后续样式都要在这个下面才会生效。
3. 定义`.layout-sider`类样式,定义侧边栏宽度、最小高度。
4. 定义`.layout-sider-dark`类样式,定义侧边栏`dark`主题下的背景色。
### index.js
`src/layout/index.js`
在`nodejs`中,`index.js`在引入的时候,一般不用写,常见用法就是,在自己写的组件包下,创建一个`index.js`文件,引入自己的组件并导出,对组件进行统一管理。
这样的话,在别人引用咱们的组件的时候,就只需要知道是layout下的组件就行了,没必要知道具体是那个`vue`文件实现的。
```javascript
import Layout from "./index.vue"; // 引入组件的实现文件,可以看到,这里是必须引用到具体哪个文件实现了Layout的。
export {
Layout
};
```
### 用法
`src/App.vue`
下面就是引入组件的用法。可以看到,使用index.js,对使用方来说,隐藏了代码的具体实现文件。实现了引用的简化和统一管理。
```vue
//使用
```
### 样式
#### 全局变量
`src/style/variables.less`
这个文件主要存储整个项目中,样式变量,方便以后对框架部分样式进行调整,而不影响整个应用,因为大家都是用了全局变量。
```less
// common
@sider-width: 200px;
@header-height: 64px;
@font-size: 14px;
// layout
@layout-height: 100vh;
@layout-sider-width: @sider-width;
@layout-sider-dark-bg-color: rgb(0, 20, 40);
// layout-light
@layout-sider-light-bg-color: #fff;
```
#### 全局样式
`src/style/index.less`
这个文件是全局样式,这里只引入了`tailwind css`,因为这里基本包括了常见的初始化样式。比如:`body`等元素的初始化。所以,项目搭建初期,咱们就不用写了。
```less
@tailwind base;
@tailwind components;
@tailwind utilities;
```
#### 引入全局样式
`main.js`
```javascript
...
import "./style/index.less"
...
```
给main.js中添加以上代码,就可以应用全局样式到整个项目。
### App
`src/App.vue`
修改App.vue,将Layout作为配置的唯一节点。引入全局样式。固定默认的语言为简体中文。
```vue
```
以上操作后,我们把整个Layout架子就搭建起来了。效果如图:

### AIcon组件
#### 原理
因为图标占用资源比较大,很多UI框架已经把图标独立出去了,甚至直接使用第三方图标,而且还不支持动态选择。像菜单这种,图标配置从后端获取的时候,就很不友好,因为后端给的一定是字符串,而不是组件,所以我们就要把字符串转化成组件。怎么转化呢?
幸运的是,我们可以使用`Vue`提供的内置组件来实现,它的作用,就是将一段字符串转化为组件。
``` vue
```
在上面的例子中,被传给 `:is` 的值可以是以下几种:
- **被注册的组件名**
- 导入的组件对象
这里的原理,就是:`component` 组件传入的`:is`属性,就是 **被注册的组件名**。
什么意思呢?
1. 组件必须被注册了,并且有名字
2. 想使用已经注册的组件,可以直接使用,但是这样就和动态没关系了。
3. 动态使用,就直接给`component` 组件传入的`:is`属性传递这个组件的名字。
比如:有个组件A,可以一下两种使用方法。
#### 静态组件
```vue
```
像这种,不能传递参数来改变组件的渲染的(如A的渲染,无法改变,智能改代码让其改变渲染的方式)叫做,静态组件。
#### 动态组件
```vue
切换成C
```
在这里,导入了`A`、`B`、`C`三个组件,默认显示组件`A`,因为`componentName`默认就是`A字符串`。`component`组件会自己在全局和局部上下文去找名字叫`A`的已经注册的组件,找到后用`A组件`替代自己。
如果点击按钮,就会切换成C组件,原理和A的显示一样。
#### AIcon实现
##### 安装ElementUI-Icon
首先得安装UI框架抽离出去的组件。
```shell
npm install @element-plus/icons-vue
```
#### 注册插件
`src/plugins/icon.js`
注册的核心类,封装了element-plus的icon注册,并导出了`setupIcon`注册函数。需要在main.js里调用。
```javascript
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
export function setupIcon(app){
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
}
```
#### 注册
```javascript
...
const app = createApp(App)
setupIcon(app);
...
```
调用`setupIcon`进行注册。
#### AIcon组件封装
##### 结构

`src/components/icon/index.vue`
```vue
```
1. 这个组件定义了一个name属性,用于外部传递组件名称,供``组件使用。
2. 给``组件绑定了props属性,其实就是想将`AIcon`当做``使用,参数直接全部绑定给他就行了。
3. 为什么要使用``组件?因为他提供了一些属性对我们来说很有用,比如:size(大小)、color(颜色)
`src/components/icon/index.js`
```javascript
import AIcon from "./index.vue"
export { AIcon }
```
这个前面解释过,就不在重复解释。导出`AIcon`组件
#### AIcon 组件使用
```vue
```
如上,给name传递一个已经注册的组件名字`Odometer`,即可显示图标。如下图:

### Sider组件
有了上面的骨架,实现了动态图标组件,接下来,我们需要实现的就是侧边栏,也就是`菜单`和`logo`的组合组件。
考虑到,菜单如果太多,就必须要有滚动条,所以,先给Sider组件,写个滚动条,幸运的是,element-plus提供了这个组件。
#### 结构

#### 滚动条
`src/layouts/sider/index.vue`
```vue
menu111
menu222
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu
menu333
menu444
```
如图:

可以看到,右侧有一个若隐若现的滚动条,这就是`el-scrollbar`
> [!NOTE]
>
> 滚动条一定要设置高度,否则无效。
>
> 如:
>
> .layout-sider {
> max-height: @layout-height;
> }
>
> @layout-height: 100vh;
>
> `vh`代表视图高度,其实就是浏览器可见区域高度。100vh代表100%视图高度,也就是100%浏览器可见区域高度。
#### logo
`src/layouts/sider/index.vue`
```vue
ElementUI Pro
```
这块很简单,flex布局,内容居中,高度用全局变量,行高度一样(64px),超出不换行。
#### menu
`src/layouts/sider/index.vue`
```vue
...
...
```
直接找了个menu的案例,修改了菜单,增加了动态图标。效果如下:

##### 去边框
可以看到,菜单右侧明显有一条表框,要去掉边框,直接覆盖样式。
```css
.layout-sider {
...
.sider-menu {
border: 0;
}
...
}
```

##### 设置背景色
查阅api,经过测试,确定只有一下几个参数可用:
```css
.layout-sider {
...
.sider-menu-dark {
--el-menu-bg-color: @layout-sider-dark-bg-color;
--el-menu-hover-bg-color: @layout-sider-dark-bg-color;
--el-menu-text-color: @layout-sider-dark-text-color;
--el-menu-active-color: @layout-sider-dark-active-color;
}
}
```
所以给菜单添加样式`.sider-menu-dark`:菜单背景色,菜单鼠标悬浮背景色,菜单文字颜色,菜单文字激活颜色,其他的参数均无效,如下:

##### css hack
但是要实现我们的目标,还是差了一些距离,如:激活背景色,激活后父菜单字体颜色,鼠标悬浮字体颜色等。
所以,现在只能靠hack css来实现了。因为element-plus没有提供变量来覆盖。
```vue
```
如上代码,添加到`src/layouts/sider/index.vue`中就行了,细心的人会发现,这个`
```
至此,Sider组件,基础版本开发完成,为什么是基础呢、因为和后端还没有交互,都是写死的静态页面。另外,还有一些动态改变主题的功能还未实现。
### Header组件
### Main组件
#### Tab组件
```shell
npm i -S vuedraggable@next
```
> [!NOTE]
>
> 这个插件和自动引入有冲突,直接按照官网给的实例,会报错,解决方法就是在main.js中添加createApp的引用,如下:
>
> `src/main.js`
>
> ```javascript
> ...
> import {createApp} from "vue";
> ...
> ```
# 路由
vue中,路由大家经常使用VueRouter,因为这个是官方提供的路由,没有可以挑选的。
## 安装
```shell
npm install vue-router@4
```
# 国际化?