Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ebe405a
change readme.md
Sep 15, 2020
85adeec
解决基本布局无法显示的问题,以及布局初始化
Sep 15, 2020
e4c639d
增加函数式组件来实现递归菜单、添加antdesign默认样式文件
Sep 16, 2020
e22a7f7
增加menu click的接口interface
Sep 16, 2020
5d0519a
chore: 增加axios、mock包
Sep 18, 2020
da6d6e7
feat: 添加vuex基础配置,并进行demo测试
xgChange Sep 19, 2020
bfd220b
feat: 添加axios配置,拦截器等、联合vuex
Sep 21, 2020
f287021
feat: 增加login页面,准备联通store
Sep 21, 2020
cfe6245
feat: 完成login、添加axios泛型
Sep 22, 2020
40a7b25
feat: 暂未完成权限控制,动态菜单 (30%)
Sep 22, 2020
ebfde92
feat: 修复路由拦截的bug,还是存在router的bug
Sep 24, 2020
21ba528
bug: 重写路由的push方法,解决重复引用路由的问题
xgChange Sep 24, 2020
a9c2e2f
feat: 添加enter事件、nprogress过渡条、sassloader加载variables.scss
Sep 25, 2020
12d6c15
feat: 添加路由权限控制
xgChange Sep 26, 2020
a8b6bac
docs: 删除注释
xgChange Sep 26, 2020
df6884d
feat: 添加路由跳转,完成权限控制
xgChange Sep 26, 2020
7b4f391
docs: 添加md笔记,关于权限控制
Sep 27, 2020
cfcdb85
feat: 解决重写push方法时,无法正确定位类型
xgChange Oct 5, 2020
4c78675
feat: 增加vue.config.js的一些基础配置
Oct 9, 2020
2d08f7d
feat: 添加多页面配置,devserver下通过/subpage.html访问
Nov 2, 2020
f6a3988
feat: 改变route结构、暂未解决动态点亮菜单栏
Nov 2, 2020
28266f7
feat: 增加刷新页面时动态点亮、和展开二级以上菜单栏
xgChange Nov 2, 2020
1db809d
feat: 修改动态点亮菜单
Nov 3, 2020
af5e225
temp
Nov 3, 2020
85f4a37
feat: 基础布局visual界面
Nov 3, 2020
edf1b71
feat: 增加手风琴特效的函数是组件
Nov 4, 2020
ba0b922
feat: 优化了下手风琴过渡效果
xgChange Nov 4, 2020
d5b9282
feat: 添加svg基础配置
Nov 5, 2020
6a84d61
feat: 完成svg配置,和左边工具栏布局,增加eslint忽视文件
xgChange Nov 5, 2020
9594cb9
visual页面布局height 100%
Nov 6, 2020
13f470e
feat: 调整可视化页面布局、增加移动端适配vw+rem
xgChange Nov 7, 2020
26c150b
feat: 优化visual的左侧栏的动态点击效果,初始化supage的components
xgChange Nov 9, 2020
1275778
bug: 测试一下不同屏幕的显示
Nov 10, 2020
676b894
feat: 初步写collapse组件
Nov 12, 2020
6aba6cf
feat: 增加collapse组件isExpand的切换
xgChange Nov 12, 2020
a79cf7f
feat: 修复visual的布局不适应的bug,完成cllapse组件和优化transition组件
xgChange Nov 15, 2020
a8ff776
feat: 新增navbar组件
xgChange Nov 17, 2020
e739d71
feat: 增加search组件、待完善样式和逻辑细节
Nov 18, 2020
492690d
feat: 完善了search框
Nov 19, 2020
6fa8a4b
feat: 拆分search组件中的input组件,为i-input
Nov 19, 2020
8f97cf8
note: 添加和vue组件事件机制的说明,以及代码优化
Nov 23, 2020
e683c9e
feat: form组件30%
Nov 23, 2020
885fc02
feat: form组件50%,校验功能暂未完善
Nov 24, 2020
fce2289
form组件完成80%
xgChange Nov 24, 2020
b9c1876
feat: form组件主要功能完成,添加labelWidth和原生submit
Nov 25, 2020
43626be
feat: button组件添加scss,完成70%
Nov 25, 2020
cba48a6
feat: 完成button组件,准备写界面可视化
xgChange Nov 25, 2020
42e13b8
feat: 添加jsx组件写法,以及一次导入components、实现外部组件和iframe通信(暂未完成)
Nov 26, 2020
781057a
test: 测试一下tsx的一些高级语法
xgChange Nov 26, 2020
e381ff4
feat: 初步做了个雏形,可点击菜单栏,显示组件,暂未添加数据
Nov 27, 2020
5418987
feat: 添加配置文件选项进行测试,组件还是有些bug,无法获取的值
Nov 30, 2020
ee6015a
feat: 增加添加组件时的事件可配置
Dec 4, 2020
b8ec0b1
feat: 调整jsx的slots展示方式,调整slots为数组
Dec 7, 2020
bd072b4
feat: 补充提交
Dec 7, 2020
f78202b
bug: 暂未解决antdesign的tab布局
Dec 7, 2020
4e151fd
feat: 调整visualRight布局、为解决form的校验bug
xgChange Dec 7, 2020
f0c38f6
feat: 解决form表单无法验证的bug,测试可以通过button提交表单
xgChange Dec 8, 2020
b8c46d4
feat: 添加鼠标事件,移动到组件时添加组件边框
xgChange Dec 9, 2020
d5e675d
feat: 添加postmessage通信和改写鼠标移动事件
Dec 15, 2020
c553d0f
feat: 暂未完成 tips组件 互斥效果
Dec 16, 2020
7e027bf
feat: 添加tips组件,重新优化添加border和tips的逻辑,正在写rightVisual的面板逻辑
Dec 22, 2020
173f69c
feat: 完成visualright面板list的布局、添加动态组件去切换相应组件
xgChange Dec 22, 2020
f2c7c2e
feat: 修改模板更新逻辑(暂未完成)
Dec 23, 2020
78f0d2a
测试mac的提交
xgChange Oct 31, 2021
9972880
切换为sass-loader、dart-sass
xgChange Nov 4, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VUE_APP_BASE_API = '/api/'
1 change: 1 addition & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VUE_APP_BASE_API = '/api/production/'
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
src/assets/icons

src/subpage/index-temp.vue
6 changes: 5 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ module.exports = {
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'prefer-rest-params': 'off',
'prefer-spread': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'off'
}
}
12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# vue-ts-manangerment
# 这是一个vue和ts编写的可视化操作系统

## 测试一下mac的git

## Project setup
```
Expand All @@ -14,11 +16,3 @@ yarn serve
```
yarn build
```

### Lints and fixes files
```
yarn lint
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
5 changes: 3 additions & 2 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"]
};
presets: ['@vue/cli-plugin-babel/preset'],
plugins: [['import', { libraryName: 'ant-design-vue', libraryDirectory: 'es', style: 'css' }]]
}
293 changes: 293 additions & 0 deletions md/note.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
# 一些笔记记录

## 环境配置

```javascript
// 各个环境配置项的权重大小
.env.[mode].local > .env.[mode] > .env.local > .env
```

## 动态加载路由,实现路由权限控制

1. 将路由分为 **动态路由** 和 **固定路由**

`固定路由:是一些不随用户权限改变的路由,比如/login、/register、/404等`

`动态路由:跟随用户权限改变的路由`

参数说明:
```javascript
{
name: '/', // 因为我后面生成侧边栏时,要用到 :key="name", 而通过菜单的点击事件,正好可以获取 name, 然后进行跳转
meta: {
hidden: false, // 是否在菜单栏中显示该路由
iconType: '' // 菜单项的icon
}
}
```

```javascript
// src/router/routes.ts

// 无权限路由,固定路由
import UserRoute from './module/user'
import TestRoute from './module/test'
import VisualRoute from './module/visual'

export const constantRoutes: Array<RouteConfig> = [
{
path: '/',
component: MyLayout,
name: '/',
redirect: '/',
meta: {
title: '首页',
hidden: false,
iconType: 'bank'
},
children: [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue'),
meta: {
hidden: true
}
}
]
},
{
path: '/login',
name: '/login',
meta: {
title: '登录',
hidden: true
},
component: () => import('../views/login/index.vue')
}
]

export const asyncRoutes: Array<RouteConfig> = [UserRoute, TestRoute, VisualRoute]
```

```javascript
// src/router/module/visual.vue 中
export default {
path: '/visual',
component: () => import('@/views/visual/index.vue'),
name: '/visual',
meta: {
title: '可视化编辑',
role: ['admin'],
iconType: 'reconciliation',
hidden: false // 是否显示在菜单
}
}
```

2. 解决Vue router 报 **NavigationDuplicated**(重复导航到同一路由) 和 **Redirected when going from**错误

`这是因为在vue router升级到3.1之后,$router.push()方法改成了Promise,所以需要catch push方法产生的错误`

```javascript
// src/router/index.ts 中
import Vue from 'vue'
import VueRouter, { RawLocation } from 'vue-router'
import { constantRoutes } from './routes'

Vue.use(VueRouter)

// 解决重复引用同一个路由的问题,重写push
const _push = VueRouter.prototype.push
VueRouter.prototype.push = function(location: RawLocation) {
return (_push.call(this, location) as any).catch((err: Error) => err)
}

const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: constantRoutes
})

export default router
```

3. 在vuex中新增permission模块(可参考vuex在ts中的写法)

```javascript
// src/store/modules/permission.ts

// @description 判断是否有权限,设置meta.role
function hasPermission(route: RouteConfig, role: string) {
if (route.meta && route.meta.role && route.meta.role.length) {
// 返回是否有 用户对应的权限
return route.meta.role.includes(role)
} else {
// 如果没有设置则为公用
return true
}
}

// @description 过滤在route.ts中设置的asyncRoutes
function filterAsyncRoutes(routes: RouteConfig[], role: string) {
const res: RouteConfig[] = []
routes.forEach(item => {
if (hasPermission(item, role)) {
if (item.children) {
item.children = filterAsyncRoutes(item.children, role)
}
res.push(item)
}
})

return res
}

@Mutation
SET_ROUTES(routes: RouteConfig[]) {
this.routes = constantRoutes.concat(routes)
this.asyncRoutes = routes
}

@Action
GenerateRoutes(role: string) {
// 如果是admin,则拿到全部的路由
let tempRoutes = []
if (role === 'admin') {
tempRoutes = asyncRoutes
} else {
tempRoutes = filterAsyncRoutes(asyncRoutes, role)
}
this.SET_ROUTES(tempRoutes)
}
```

4. 新增src/permission.ts 文件,在里面进行路由拦截控制

**tips: 如果没有token,则会跳转到login页面,但是进入login页面之前又会执行beforeEach钩子,造成无限递归。所以最好加一个判断,跳出递归。**

```javascript
import router from './router/index'
import { UserModule } from '@/store/modules/user'
import { PermissionModule } from '@/store/modules/permission'
import NProgress from 'nprogress'

const whiteList = ['/login']

router.beforeEach(async (to, from, next) => {
NProgress.start()
if (UserModule.token) {
if (to.path === '/login') {
next({ path: '/' })
} else {
if (Object.keys(UserModule.userInfo).length === 0) {
try {
const role = await UserModule.getUserInfo()
PermissionModule.GenerateRoutes(role)

// 通过router的addRoutes方法可以实现动态加载路由
router.addRoutes(PermissionModule.asyncRoutes)
next({ path: to.path, replace: true })
} catch (error) {
// 获取用户信息失败,重新登录
next('/login')
}
} else {
// 如果获取了用户信息,则 go on
next()
}
}
} else {
// 解决无限递归进入login页面
if (whiteList.includes(to.path)) {
next()
} else {
next('/login')
}
}
})
```

5. 至此,根据权限动态加载路由就实现了~ (侧边的菜单栏可以通过vuex中的 PermissionModule.routes,递归生成一二三级菜单)

## 布局方面

1. 垂直水平居中

```css
/* 使用 flex margin来实现水平垂直居中 */
.parent {
display: flex; /*或者 justify-content: center*/
}

.child {
margin: 0 auto;
}

/* 使用定位来撑起盒子; child盒子设置top和bottom它的高度和parent一样 */
.parent {
position: relative;
padding: 16px 0;
}
.child {
position: absolute;
top: 0;
bottom: 0;
}
```

## 关于vue中的事件监听($emit、$on、$listeners)

1. Vue中的$emit、$on等,使用的是**发布订阅模式**

`如果在同一个事件名上监听多个事件,则在emit的时候会触发所有监听的事件。`

2. 关于 **$listeners** 的一些注意事项
> 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

`只包含了v-on监听器的(@事件名)`

**所以通过v-on="$listeners"传下去的事件可以通过后面组件this.$emit去触发,发布订阅模式(触发所有事件名监听的事件)**

`例如在 subpage -> i-search -> i-input 三层组件中`

```html
<!-- subpage组件 -->
<i-search
v-model="inputValue"
iconPosition="right"
placeholder="请输入关键字搜索"
showAction
class="nav-bar-content_iSearch"
@search="handleSearch"
@cancle="handleCancle"
></i-search>
```

```html
<!-- i-search组件通过$listners将父作用域与本作用域v-on监听事件传递下去 -->
<i-input
type="text"
v-model="currentValue"
v-bind="$attrs"
v-on="$listeners"
class="i-search-content_left-box_input"
@enter="handleSearch"
></i-input>
```

```typescript
/*
在i-input中,可以通过emit('input'),触发在subpage和i-search中监听的@input事件
*/
@Emit('input')
handleInput(e: Event) {
const value = (e.target as HTMLInputElement).value
this.currentValue = value
return value
}
```
3. 关于 **$attrs**
> 简单点就是包含父作用域中,没有写进props里面的 attribute属性(class和style除外)

`通常搭配inheritAttrs使用,它的作用主要是子组件没有用props去接收父组件传过来的attribute,不会显示在html标签中`
13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@types/nprogress": "^0.2.0",
"ant-design-vue": "^1.6.5",
"async-validator": "^3.5.1",
"axios": "^0.20.0",
"core-js": "^3.6.5",
"nprogress": "^0.2.0",
"vue": "^2.6.11",
"vue-class-component": "^7.2.3",
"vue-property-decorator": "^8.4.2",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
"vuex": "^3.4.0",
"vuex-module-decorators": "^0.17.0"
},
"devDependencies": {
"@types/mockjs": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.5.0",
Expand All @@ -26,12 +33,14 @@
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"babel-plugin-import": "^1.13.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^6.2.2",
"lint-staged": "^9.5.0",
"node-sass": "^4.12.0",
"mockjs": "^1.1.0",
"prettier": "^1.19.1",
"sass": "^1.43.4",
"sass-loader": "^8.0.2",
"typescript": "~3.9.3",
"vue-template-compiler": "^2.6.11"
Expand Down
Loading