Skip to content

Commit

Permalink
refactor: use vue-directive-normalizer and refactor outside directive…
Browse files Browse the repository at this point in the history
…, with test cases
  • Loading branch information
Justineo committed May 29, 2019
1 parent 0b5b3ce commit bed30df
Show file tree
Hide file tree
Showing 5 changed files with 375 additions and 77 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

* [^] 修正 `Tree` 组件 `item-label` slot 没有正常渲染的问题。
* [^] 修正 `longpress` 指令 `repeat` 参数的默认值为 `false`
* [^] 修正 `resize` 指令没有正确处理 `leading` 参数的问题。
* [^] 修正 `outside` 指令没有准确判断参数是否变更的问题。

## 1.0.0-alpha.25

Expand Down
3 changes: 2 additions & 1 deletion packages/veui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test": "cross-env NODE_ENV=test BABEL_ENV=test karma start --single-run"
"test": "cross-env NODE_ENV=test BABEL_ENV=test karma start --single-run",
"test:start": "cross-env NODE_ENV=test BABEL_ENV=test karma start"
},
"module": "index.js",
"dependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/veui/src/directives/drag.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function clear (el) {
dragData.handler.destroy()
el.removeEventListener('mousedown', dragData.mousedownHandler)
el.__dragData__ = null
el.__dragOldOptions__ = null
}

function getOptions (binding, vnode) {
Expand Down
106 changes: 30 additions & 76 deletions packages/veui/src/directives/outside.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import {
invert,
isFunction,
uniqueId,
remove,
find,
isString,
noop,
isEqual,
pick
} from 'lodash'
import { normalize } from 'vue-directive-normalizer'
import { invert, uniqueId, remove, isEqual, difference, omit } from 'lodash'
import { getNodes } from '../utils/context'
import { contains } from '../utils/dom'
import { getNumberArg } from '../utils/helper'

const OPTIONS_SCHEMA = {
value: 'handler',
arg: 'refs[]',
modifiers: {
trigger: ['click', 'mousedown', 'mouseup', 'hover', 'focus'],
excludeSelf: false,
delay: 0
}
}

const TRIGGER_EVENT_MAP = {
hover: 'mouseout',
Expand Down Expand Up @@ -46,7 +46,7 @@ function initBindingType (type) {
event,
e => {
handlerBindings[type].forEach(item => {
item[key] && item[key].handler(e)
item[key] && item[key].realHandler(e)
})
},
true
Expand All @@ -61,54 +61,6 @@ function getElementsByRefs (refs, context) {
return elements
}

function parseParams (arg, modifiers, value) {
let refs = arg ? arg.split(',') : []
let handler
let trigger =
find(TRIGGER_TYPES, triggerType => triggerType in modifiers) || 'click'
// delay 表示如果鼠标移动到 includeTargets 元素之外多少毫秒之后,才会触发 handler
let delay = getNumberArg(modifiers, 0)
let excludeSelf = !!modifiers.excludeSelf

// 如果 value 是 Function 的话,其余参数就尽量从 modifier、arg 里面去解析
// 否则从value里面去解析
if (isFunction(value)) {
handler = value
} else {
let normalizedValue = value || {}
handler = isFunction(normalizedValue.handler)
? normalizedValue.handler
: noop

if (normalizedValue.refs) {
refs = Array.isArray(normalizedValue.refs)
? normalizedValue.refs
: isString(normalizedValue.refs)
? normalizedValue.refs.split(',')
: [normalizedValue.refs]
}

trigger = normalizedValue.trigger || trigger || 'click'

if ('delay' in normalizedValue) {
let delayNum = Number(normalizedValue.delay) || 0
delay = delayNum >= 0 ? delayNum : 0
}

if ('excludeSelf' in normalizedValue) {
excludeSelf = !!normalizedValue.excludeSelf
}
}

return {
refs,
handler,
trigger,
delay,
excludeSelf
}
}

/**
* 判断 element 在 DOM 树结构上是否被包含在 elements 里面
*
Expand Down Expand Up @@ -196,33 +148,35 @@ function clear (el) {
})
}

function refresh (el, { value, arg, modifiers }, vnode) {
const params = parseParams(arg, modifiers, value, vnode.context)
let { trigger, refs, excludeSelf, delay } = params
let key = getBindingKey(trigger)
const OMIT_OPTIONS = ['refs', 'id', 'realHandler']

// 真正发生了变化,才重刷
let fields = [
'refs',
'trigger',
'excludeSelf',
...(trigger === 'hover' ? ['delay'] : [])
]
function isEqualOption (o1, o2) {
return (
difference(o1.refs, o2.refs).length === 0 &&
isEqual(omit(o1, OMIT_OPTIONS), omit(o2, OMIT_OPTIONS))
)
}

function refresh (el, binding, vnode) {
let options = normalize(binding, OPTIONS_SCHEMA)
let { trigger, refs, excludeSelf, delay } = options
let key = getBindingKey(trigger)

let prevParams = pick(el[key], fields)
let oldOptions = el[key]

if (isEqual(prevParams, pick(params, fields))) {
if (oldOptions && isEqualOption(options, oldOptions)) {
return
}

clear(el)
el[key] = {
id: uniqueId('veui-outside-'),
handler: generate(el, params, vnode.context),
handler: options.handler, // to compare with new one
realHandler: generate(el, options, vnode.context),
trigger,
refs,
excludeSelf,
...(trigger === 'hover' ? { delay } : {})
delay
}
addBinding(trigger, el)
}
Expand Down
Loading

0 comments on commit bed30df

Please sign in to comment.