docs(README.md): 项目文档修改

This commit is contained in:
郝先瑞 2022-01-16 00:04:27 +08:00
parent e2f24f5429
commit 21d61b7a06
2 changed files with 31 additions and 607 deletions

636
README.md
View File

@ -1,623 +1,49 @@
## 技术栈官网
[![](https://img.shields.io/badge/Author-有来技术-orange.svg)](https://gitee.com/wangjiabin-x/uh5)
![](https://img.shields.io/badge/youlai--mall-v2.0.0-blue)
[![](https://img.shields.io/github/stars/hxrui/youlai-mall.svg?style=social&label=Stars)](https://github.com/hxrui/youlai-mall/stargazers)
[![](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/hxrui/youlai-mall/blob/master/LICENSE)
![](https://img.shields.io/badge/SpringBoot-2.5.2-brightgreen.svg)
![](https://img.shields.io/badge/SpringCloud-2020-green.svg)
![](https://img.shields.io/badge/vue--element--admin-v4.4.0-orange)
- vue3: https://v3.cn.vuejs.org/guide/introduction.html
**线上预览地址:** http://www.youlai.tech
- vite2: https://cn.vitejs.dev/guide/
#### 项目预览
- element-plus: https://element-plus.gitee.io/zh-CN/component/button.html
| ![image-20210621004954228](https://gitee.com/haoxr/image/raw/master/image-20210621004954228.png) | ![image-20210621005011310](https://gitee.com/haoxr/image/raw/master/image-20210621005011310.png) |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
|![](https://gitee.com/haoxr/image/raw/master/30719657a4b183428a2472231fee55a6_image-20210621005037964.png) | ![image-20210621005123432](https://gitee.com/haoxr/image/raw/master/image-20210621005123432.png) |
- vue-router4 : https://next.router.vuejs.org/zh/introduction.html
- ~~vuex4https://next.vuex.vuejs.org/zh/index.html~~ (pinia替代)
- pinia: https://pinia.vuejs.org
#### 技术栈
## Vite项目构建
- **前端技术栈:** vue3、vite2、element-plus、typescript、vue-element-admin
Vite是一种新型前端构建工具能够显著提升前端开发体验。
[Vite 官方中文文档](https://cn.vitejs.dev/ )
#### 项目地址
项目构建命令:
| 项目名称 | 源码地址 |项目名称 | 源码地址 |
| ---------- | ------------------------------------------------------------ |---------- | ------------------------------------------------------------ |
| 微服务后台 | [youlai-mall](https://gitee.com/youlaitech/youlai-mall) | 微信小程序 | [youlai-mall-weapp](https://gitee.com/youlaitech/youlai-mall-weapp) |
| 管理前端 | [youlai-mall-admin](https://gitee.com/youlaitech/youlai-mall-admin) |APP应用 | [youlai-mall-app](https://gitee.com/youlaitech/youlai-mall-app) |
```shell
npm init vite@latest vue3-element-admin --template vue-ts
cd vue3-element-admin
npm install
npm run dev
```
访问本地: http://localhost:3000
#### 项目启动
## vue-router
1. 本机安装Node环境
2. npm install
3. npm run dev
4. 访问 http://localhost:9527
```text
npm install vue-router@next
```
#### 项目文档
src 下创建 router/interface.ts
[项目文档地址](https://www.cnblogs.com/haoxianrui/)
```typescript
import {createRouter, createWebHashHistory, RouteRecordRaw} from 'vue-router'
import HelloWord from '../components/HelloWorld.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '',
redirect: (_) => {
return {path: '/home'}
}
},
{
path: '/home',
name: 'HelloWord',
component: HelloWord
}
]
#### 联系信息
因为微信交流群满200人只能通过邀请进入如果想进入交流群学习可添加以下开发人员备注“**有来**“由其拉进群。
const router = createRouter({
history: createWebHashHistory(),
routes: routes
})
export default router
```
**参考文档:**
- [路由的 hash 模式和 history 模式的区别](https://www.cnblogs.com/GGbondLearn/p/12239651.html)
## pinia
```shell
npm install pinia
```
src 下创建 store/index.ts
```typescript
import { createPinia } from "pinia";
const store = createPinia();
export { store };
```
main.ts
```typescript
import {createApp} from 'vue'
import App from './App.vue'
import router from "./router";
import '@/styles/index.scss'
import { store } from "./store";
import ElementPlus from 'element-plus'
import 'element-plus/theme-chalk/index.css'
import locale from 'element-plus/lib/locale/lang/zh-cn'
import 'virtual:svg-icons-register';
// @see https://blog.csdn.net/qq_37213281/article/details/121422027
import * as ElIconModules from '@element-plus/icons'
import '@/permission'
import Pagination from '@/components/Pagination/index.vue'
import {listDictsByCode} from '@/api/system/dict'
const app = createApp(App)
// 统一注册el-icon图标
// @link https://blog.csdn.net/Alloom/article/details/119415984
for (let iconName in ElIconModules) {
app.component(iconName, (ElIconModules as any)[iconName])
}
// 全局方法
app.config.globalProperties.$listDictsByCode = listDictsByCode
app.component('Pagination', Pagination) // 全局组件
.use(store)
.use(router)
.use(ElementPlus, {locale})
.mount('#app')
```
## element-plus
```shell
npm install element-plus
```
## main.ts
```typescript
import { createApp } from 'vue'
import App from './App.vue'
import router from "./router";
import {store,key} from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app=createApp(App)
app
.use(router)
.use(store,key)
.use(ElementPlus)
.mount('#app')
```
## Vite 设置路径别名
#### 安装 @types/node
```shell
npm install --save-dev @types/node
```
或者简写
```shell
npm i -D @types/node
```
#### vite.config.ts
```typescript
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
// 在 ts 模块中加载 node 核心模块需要安装 node 的类型补充模块: npm i -D @types/node
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
// Vite2设置别名路径方式一
/**
alias:{
"/@":path.resolve("./src"),
},
**/
// Vite2设置别名路径方式二
alias: [
{
find: "@",
replacement: path.resolve("./src")
},
{
find: "@image",
replacement: path.resolve("./src/assets/images")
},
{
find: "@/router",
replacement: path.resolve("./src/router")
},
{
find: "@/store",
replacement: path.resolve("./src/store")
},
{
find: "@/api",
replacement: path.resolve("./src/api")
}
]
}
})
```
#### tsconfig.json
TS配置别名路径否则使用别名路径会报错下面关键配置 `baseUrl` 、`paths` 和 `include`
```json
{
"compilerOptions": {
...
"baseUrl": "./",
"paths": {
"@": ["src"],
"@*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
```
## Vite 环境变量配置
**官方环境变量配置文档:** https://cn.vitejs.dev/guide/env-and-mode.html
#### 配置文件
在项目根目录分别添加 `开发环境配置``生产环境配置`和`模拟环境配置`文件
开发环境配置:`.env.development`
```properties
# 开发环境变量 注意:变量必须以 VITE_ 为前缀才能暴露给外部读取
VITE_APP_TITLE = '管理系统'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/dev-api'
```
生产环境配置:`.env.production`
```properties
# 生产环境变量
VITE_APP_TITLE = '管理系统'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/prod-api'
```
模拟环境配置:`.env.staging`
```properties
# 模拟环境变量
VITE_APP_TITLE = '管理系统'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/stage-api'
```
#### 环境变量智能提示
`src/env.d.ts` 添加以下配置
```typescript
// 环境变量智能提示
interface ImportMetaEnv {
VITE_APP_TITLE: string,
VITE_APP_PORT: string,
VITE_APP_BASE_API: string
}
```
## 生产打包配置
#### package.json
```json
"scripts": {
"dev": "vite serve --mode development",
"build:prod": "vue-tsc --noEmit && vite build --mode production",
"serve": "vite preview"
}
```
#### tsconfig.json
```json
{
"compilerOptions": {
...
"skipLibCheck": true // element-plus 生产打包报错,通过此配置修改 TS 不对第三方依赖类型检查
}
}
```
执行 `npm run build:prod` 命令打包,生成的打包文件在项目根目录 `dist` 目录下
## axios 封装
#### 安装axios
```
npm i axios
```
#### 缓存工具类
**src/utils/storage.ts**
```typescript
/**
* window.localStorage 浏览器永久缓存
*/
export const Local = {
// 设置永久缓存
set(key: string, val: any) {
window.localStorage.setItem(key, JSON.stringify(val));
},
// 获取永久缓存
get(key: string) {
let json: any = window.localStorage.getItem(key);
return JSON.parse(json);
},
// 移除永久缓存
remove(key: string) {
window.localStorage.removeItem(key);
},
// 移除全部永久缓存
clear() {
window.localStorage.clear();
},
};
/**
* window.sessionStorage 浏览器临时缓存
*/
export const Session = {
// 设置临时缓存
set(key: string, val: any) {
window.sessionStorage.setItem(key, JSON.stringify(val));
},
// 获取临时缓存
get(key: string) {
let json: any = window.sessionStorage.getItem(key);
return JSON.parse(json);
},
// 移除临时缓存
remove(key: string) {
window.sessionStorage.removeItem(key);
},
// 移除全部临时缓存
clear() {
window.sessionStorage.clear();
}
};
```
#### 创建axios实例
**src/utils/request.ts**
```typescript
import axios from "axios";
import {ElMessage, ElMessageBox} from "element-plus";
import {Session} from "@/utils/storage";
// 创建 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_BASE_API as any,
timeout: 50000,
headers: {'Content-Type': 'application/json;charset=utf-8'}
})
// 请求拦截器
service.interceptors.request.use(
(config) => {
if (!config?.headers) {
throw new Error(`Expected 'config' and 'config.headers' not to be undefined`);
}
if (Session.get('token')) {
config.headers.Authorization = `${Session.get('token')}`;
}
}, (error) => {
return Promise.reject(error);
}
)
// 响应拦截器
service.interceptors.response.use(
({data}) => {
// 对响应数据做点什么
const {code, msg} = data;
if (code === '00000') {
return data;
} else {
ElMessage({
message: msg || '系统出错',
type: 'error'
})
return Promise.reject(new Error(msg || 'Error'))
}
},
(error) => {
const {code, msg} = error.response.data
if (code === 'A0230') { // token 过期
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 跳转登录页
ElMessageBox.alert('当前页面已失效,请重新登录', '提示', {})
.then(() => {
})
.catch(() => {
});
}
return Promise.reject(new Error(msg || 'Error'))
}
);
// 导出 axios 实例
export default service
```
## HelloWorld.vue
```typescript
<template>
<el-input v-model="num"/>
<el-button @click="handleClick">点击+1</el-button>
</template>
<script lang="ts">
import {defineComponent, computed} from 'vue'
import {useStore} from '@/store';
export default defineComponent({
setup() {
const store = useStore()
const num = computed(()=>{
return store.state.count
})
const handleClick = () => {
store.commit('increment')
}
return {
num,
handleClick
}
},
})
</script>
```
## App.vue
```typescript
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<router-view/>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
```
## SVG图标
- [使用手册(详细)](https://github.com/anncwb/vite-plugin-svg-icons/blob/main/README.zh_CN.md)
1. 安装
```
npm i vite-plugin-svg-icons -D
```
2. 配置插件
源码坐标:[vite.config.ts](vite.config.ts)
```
viteSvgIcons({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
})
```
3. 组件封装
源码坐标:[src/components/SvgIcon/index.vue](src/components/SvgIcon/index.vue)
4. 使用示例
源码坐标:[src/components/IconSelect/index.vue](src/components/IconSelect/index.vue)
## 跨域处理
vite.config.ts 跨域配置
```
// 本地反向代理解决浏览器跨域限制
server: {
host: 'localhost',
port: Number(env.VITE_APP_PORT),
open: true, // 运行自动打开浏览器
proxy: {
[env.VITE_APP_BASE_API]: {
target: 'http://localhost:9999',
changeOrigin: true,
rewrite: path => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
}
}
}
```
## NProgress 进度条
1. 安装
```
npm install --save nprogress
```
2. 使用案例
源码坐标:[permission.ts](src/permission.ts)
```
import NProgress from 'nprogress';
import 'nprogress/nprogress.css'
NProgress.configure({showSpinner: false}) // 进度环显示/隐藏
router.beforeEach((to, from, next) => {
NProgress.start()
...
})
router.afterEach(() => {
NProgress.done()
})
```
## 富文本编辑器 wangEditor
- [官方文档](https://www.wangeditor.com/v5/)
- [Vue3 使用](https://www.wangeditor.com/v5/guide/for-frame.html#vue3)
- [Vue3 示例](https://github.com/wangfupeng1988/vue3-wangeditor-demo)
1. 安装
```
# 安装 editor
npm install @wangeditor/editor --save
# 安装 Vue3 组件
npm install @wangeditor/editor-for-vue@next --save
```
2. 组件封装
- 源码坐标:[src/components/WangEditor/index.vue](src/components/WangEditor/index.vue)
- wangEditor自定义图片上传
```aidl
const editorConfig = {
placeholder: '请输入内容...',
MENU_CONF: {
uploadImage: {
async customUpload(file, insertFn) {
uploadFile(file).then(response => {
const url = response.data
insertFn(url)
})
}
}
}
}
```
3. 使用示例
源码坐标:[src/views/pms/goods/components/GoodsInfo.vue](src/views/pms/goods/components/GoodsInfo.vue)
## 列表排序 sortablejs
1. 安装
```
npm install sortablejs --save
```
| ![](https://gitee.com/haoxr/image/raw/master/default/113__6c5ed5b1b73ea9cd4cf32848ed350c07_b9b214638a2a406e52dbf51e9bf9a2ef.png) | ![](https://gitee.com/haoxr/image/raw/master/hxr.jpg) | ![](https://gitee.com/haoxr/image/raw/master/huawei.jpg) | ![](https://gitee.com/haoxr/image/raw/master/default/1625149769(1).png) |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| ![](https://gitee.com/haoxr/image/raw/master/default/7488479b1e2c193b04b56d1e0ff640c.jpg) | ![image-20210701232803265](https://gitee.com/haoxr/image/raw/master/default/image-20210701232803265.png) | ![](https://gitee.com/haoxr/image/raw/master/default/20210701234946.png) | ![](https://gitee.com/haoxr/image/raw/master/default/image-20210702002909113.png) |## 联系信息

View File

@ -109,8 +109,6 @@ import {listMembersWithPage} from '@/api/ums/member'
import {reactive, ref, onMounted, toRefs} from 'vue'
import {ElTable, ElMessage, ElMessageBox} from 'element-plus'
import {listCascadeCategories} from "@api/pms/category";
import {listGoodsWithPage} from "@api/pms/goods";
const state = reactive({
//