Skip to content

Commit

Permalink
Feat: 对话框默认可拖拽
Browse files Browse the repository at this point in the history
Perf: 路由缓存优化
  • Loading branch information
Maorey committed Feb 18, 2020
1 parent 2da9980 commit 7f3bd5e
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 34 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# 更新日志

## v 1.2.0

- 路由缓存优化
- 对话框默认可拖拽

## v 1.1.0

- 细节细节还是细节
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e
- 浏览器默认样式重置
- `Transition` 动画样式
- 字体图标样式
- 公共组件默认样式(使支持换肤, 使用[BEM](https://en.bem.info)约定[参考链接](https://www.ibm.com/developerworks/cn/web/1512_chengfu_bem/))
- 公共组件样式([BEM](https://en.bem.info)约定[参考链接](https://www.ibm.com/developerworks/cn/web/1512_chengfu_bem/))

均应使用 [CSSModule](https://vue-loader-v14.vuejs.org/zh-cn/features/css-modules.html)(开发环境class名:`[folder]__[name]_[local]-[emoji]$`), 以更好的模块化和复用、打包样式

Expand All @@ -235,7 +235,7 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e

> 推荐使用 [TypeScript](https://www.tslang.cn)

- JavaScript/TypeScript 代码风格为 [**JavaScript standard**](https://standardjs.com/rules-zhcn.html), 除了以下区别:
- JavaScript/TypeScript 代码风格为 [**JavaScript standard**](https://standardjs.com/rules-zhcn.html), 主要有以下区别:

- 使用单引号
- 不要句尾分号
Expand Down Expand Up @@ -267,8 +267,9 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e

- `enum/type/interface` 需要导出的直接 `export` (否则可能会得到 undefined), 其他的除了字典(硬编码)外, 先定义再`export`(IDE 提示更友好), 并且`export`语句放到最后
- 不要使用 `$` 作为组件事件名, 该名字已被[异步组件刷新](src/utils/highOrder.ts)占用
- 为避免 [Vue属性名](https://cn.vuejs.org/v2/style-guide/#私有属性名-必要) 冲突, 私有属性请使用 `$_` 作为一般命名空间(在保证易维护的前提下可以使用单字母, 但尽量避免), `_$` 作为`全局/跨组件/hack`命名空间
- 路由请**全部**使用异步组件(`@utils/highOrder getAsync`), 以使路由及其**子(异步)组件**可以局部刷新
- CSS Modules class 名使用 `camelCase` (global 可以 kebab-case), 选择器嵌套**不应超过三层**
- CSS Modules class 名使用 `camelCase`, 选择器嵌套**不应超过三层**
- <a id="全局scss"></a>**全局 sccs** _(包含<a href="#别名">各别名</a>下[.env](.env) `GLOBAL_SCSS`变量指定的文件)_ 中不要出现具体样式, 也不要有[`:export{}`](https://github.com/css-modules/icss#export)(应在 `scss/export` 目录下或 `export*.scss` 中使用); 为保证`ts/js`中引入时 scss 变量注入正确(使用缓存会导致无法对相同文件多次注入变量,不用缓存显然不合理), 应在合适的 scss 文件中引入目标样式源码:
```scss
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vue-tpl",
"author": "毛瑞 <[email protected]>",
"version": "1.1.1",
"version": "1.2.0",
"private": false,
"license": "MIT",
"keywords": [
Expand Down
28 changes: 18 additions & 10 deletions src/components/RouterViewTransparent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,29 @@
*/
import { Component } from 'vue'

let counter = 0
/// [import] vue组件,其他,CSS Module ///
// import { getAsync } from '@/utils/highOrder'
// import STYLE from './index.module.scss'

/// 常量(UPPER_CASE),单例/变量(camelCase),函数(无副作用,camelCase) ///
// const ModuleOne: any = getAsync(() =>
// import(/* webpackChunkName: "ihOne" */ './ModuleOne')
// )

export default {
name: 'RVT',
beforeCreate(this: any) {
this.$vnode.data.key = counter++ // hack key
},
created(this: any) {
this.d = { props: { max: 5 } }
this.k = { key: 0 }
this.a = this.$router
this.b = this.$route.meta
this.c = this.$vnode.data.key || this.b.code
this.d = { key: this.c, props: { max: 3 } }
},
render(this: any, h) {
const meta = this.$route.meta
this.d.props.exclude = (meta.$ || 0).e // for 依赖收集
this.k.key = meta.name
const meta = this.a.currentRoute.meta

this.d.props.exclude = (this.b.$ || 0).e // for 依赖收集
this.c === meta.code && (this.e = meta.name)

return h('KeepAlive', this.d, [h('RouterView', this.k)])
return h('KeepAlive', this.d, [h('RouterView', { key: this.e })])
},
} as Component
91 changes: 91 additions & 0 deletions src/libs/elDialogDragable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// 处理拖拽
function handleDragable(this: IObject) {
const domRoot = this.$el
const dragable = this.dragable
const domDrag = domRoot.querySelector('.el-dialog__header')

if (dragable) {
const body = document.body
const domPos = domRoot.querySelector('.el-dialog')
const POS = domPos.currentStyle || window.getComputedStyle(domPos, null)

domDrag.style.cursor = 'move'
domDrag.addEventListener(
'mousedown',
(this._$d = (event: MouseEvent) => {
const orginTop = POS.top
const orginLeft = POS.left
const top =
orginTop.indexOf('%') > 0
? body.clientHeight * (parseFloat(orginTop) / 100)
: parseFloat(orginTop)
const left =
orginLeft.indexOf('%') > 0
? body.clientWidth * (parseFloat(orginLeft) / 100)
: parseFloat(orginLeft)

const dx = event.clientX - domDrag.offsetLeft
const dy = event.clientY - domDrag.offsetTop
const onmousemove = (event: MouseEvent) => {
domPos.style.top = event.clientY - dy + top + 'px'
domPos.style.left = event.clientX - dx + left + 'px'
}
const onmouseup = () => {
body.removeEventListener('mousemove', onmousemove)
body.removeEventListener('mouseup', onmouseup)
}
body.addEventListener('mousemove', onmousemove)
body.addEventListener('mouseup', onmouseup)

if (this._$t === undefined) {
this._$t = orginTop
this._$l = orginLeft
}
})
)

if (!this._$v) {
this._$v = 1
const orginAfterLeave = this.afterLeave
this.afterLeave = () => {
if (this._$t !== undefined) {
domPos.style.top = this._$t
domPos.style.left = this._$l
}
orginAfterLeave.apply(this, arguments)
}
// 改为 afterLeave
// this.$watch('visible', (visible: boolean) => {
// if (!visible && this.dragable) {
// domPos.style.top = this._$t
// domPos.style.left = this._$l
// }
// })
this.$on('hook:beforeDestroy', () => {
domDrag.removeEventListener('mousedown', this._$d)
})
}
} else {
domDrag.style.cursor = ''
domDrag.removeEventListener('mousedown', this._$d)
}
}

/** hack: 使ElDialog支持 props dragable (默认true) 允许拖拽
*/
export default (ElDialog: IObject) => {
const options = ElDialog.options || ElDialog

// 增加 props: dragable
;(options.props || (options.props = {})).dragable = {
default: true,
type: Boolean,
}
// watch dragable
;(options.watch || (options.watch = {})).dragable = {
immediate: true,
handler() {
this.$el ? handleDragable.call(this) : this.$nextTick(handleDragable)
},
}
}
32 changes: 22 additions & 10 deletions src/pages/index/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const router = new Router(configRoute as RouterOptions)
:max="9"
:exclude="$route.meta.$.e"
>
<RouterView />
<RouterView :key="$route.meta.$.k" />
</KeepAlive>
keep-alive 缓存处理,这很hacky, 俺know
也可以通过切换key绑定实现(如下),但是:
Expand All @@ -50,25 +50,36 @@ keep-alive 缓存处理,这很hacky, 俺know
*/
let counter = 0
function refreshRoute(matched: RouteRecord[], meta: { e: any }) {
const HOOK = 'hook:beforeDestroy'
let temp: any = matched.length
let instances
while (temp--) {
if ((instances = matched[temp]).instances) {
matched = instances as any
instances = instances.instances

temp = null
temp = 0
for (temp in instances) {
;(temp = instances[temp]) && // 可能是 undefined...
(temp = temp.$vnode.componentOptions) &&
(temp = temp.Ctor.options) &&
(meta.e = temp.name = 'r' + counter++)
// 可能是 undefined...
if ((temp = instances[temp])) {
if (temp._$a) {
temp = (temp = temp.$vnode.componentOptions) && temp.Ctor.options
} else {
temp.$on(HOOK, function(this: any) {
this._$a &&
(temp = this.$vnode.componentOptions) &&
(temp = temp.Ctor.options) &&
(temp.name = this._$a)
})
temp._$a =
(temp = temp.$vnode.componentOptions) && (temp = temp.Ctor.options) && temp.name
}
temp && (meta.e = temp.name = 'r' + counter++)
}
}

if (temp === null && (matched as any).parent) {
// 没实例 - 刷她爸爸
refreshRoute([(matched as any).parent], meta)
}
// 没实例(functional) - 刷她爸爸
temp === 0 && (matched as any).parent && refreshRoute([(matched as any).parent], meta)
return
}
}
Expand Down Expand Up @@ -102,6 +113,7 @@ router.beforeEach((to, from, next) => {
} else if (fromPath !== PAGE_HOME) {
next(PAGE_HOME)
}

NProgress.done()
return
}
Expand Down
4 changes: 4 additions & 0 deletions src/pages/other/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import Notification from 'element-ui/lib/notification'
// 滚动面板【隐藏组件】
import Scrollbar from 'element-ui/lib/scrollbar'

import elDialogDragable from '@/libs/elDialogDragable'

/// 全局样式 ///
import '@/scss/icon.scss?skin='
import '@/scss/transitions.scss?skin='
Expand Down Expand Up @@ -71,6 +73,8 @@ options.components.Bar.created = function() {
}
this.clearValidate()
}
// hack: ElDialog props dragable 默认(true)允许拖拽
elDialogDragable(Dialog)

// 布局
Vue.use(Row)
Expand Down
39 changes: 29 additions & 10 deletions src/pages/other/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const router = new Router(configRoute as RouterOptions)
:max="9"
:exclude="$route.meta.$.e"
>
<RouterView />
<RouterView :key="$route.meta.$.k" />
</KeepAlive>
keep-alive 缓存处理,这很hacky, 俺know
也可以通过切换key绑定实现(如下),但是:
Expand All @@ -50,25 +50,36 @@ keep-alive 缓存处理,这很hacky, 俺know
*/
let counter = 0
function refreshRoute(matched: RouteRecord[], meta: { e: any }) {
const HOOK = 'hook:beforeDestroy'
let temp: any = matched.length
let instances
while (temp--) {
if ((instances = matched[temp]).instances) {
matched = instances as any
instances = instances.instances

temp = null
temp = 0
for (temp in instances) {
;(temp = instances[temp]) && // 可能是 undefined...
(temp = temp.$vnode.componentOptions) &&
(temp = temp.Ctor.options) &&
(meta.e = temp.name = 'r' + counter++)
// 可能是 undefined...
if ((temp = instances[temp])) {
if (temp._$a) {
temp = (temp = temp.$vnode.componentOptions) && temp.Ctor.options
} else {
temp.$on(HOOK, function(this: any) {
this._$a &&
(temp = this.$vnode.componentOptions) &&
(temp = temp.Ctor.options) &&
(temp.name = this._$a)
})
temp._$a =
(temp = temp.$vnode.componentOptions) && (temp = temp.Ctor.options) && temp.name
}
temp && (meta.e = temp.name = 'r' + counter++)
}
}

if (temp === null && (matched as any).parent) {
// 没实例 - 刷她爸爸
refreshRoute([(matched as any).parent], meta)
}
// 没实例(functional) - 刷她爸爸
temp === 0 && (matched as any).parent && refreshRoute([(matched as any).parent], meta)
return
}
}
Expand All @@ -78,6 +89,13 @@ function refreshRoute(matched: RouteRecord[], meta: { e: any }) {
const REG_REDIRECT = /\/r\//
router.beforeEach((to, from, next) => {
NProgress.start() // 开始进度条
// 关闭所有提示
const app = router.app
app.$message.closeAll()
app.$notify.closeAll()
try {
app.$msgbox.close()
} catch (error) {}

const fromPath = from.redirectedFrom || from.fullPath
const fromMatched = from.matched
Expand All @@ -102,6 +120,7 @@ router.beforeEach((to, from, next) => {
} else if (fromPath !== PAGE_HOME) {
next(PAGE_HOME)
}

NProgress.done()
return
}
Expand Down

0 comments on commit 7f3bd5e

Please sign in to comment.