mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-05 13:38:18 +08:00
flowtype reafactoring (#4945)
This commit is contained in:
parent
8bb6c2bdaa
commit
f7062b9b75
@ -3,6 +3,8 @@
|
|||||||
import { callHook } from 'core/instance/lifecycle'
|
import { callHook } from 'core/instance/lifecycle'
|
||||||
import { getFirstComponentChild } from 'core/vdom/helpers/index'
|
import { getFirstComponentChild } from 'core/vdom/helpers/index'
|
||||||
|
|
||||||
|
type VNodeCache = { [key: string]: ?VNode };
|
||||||
|
|
||||||
const patternTypes: Array<Function> = [String, RegExp]
|
const patternTypes: Array<Function> = [String, RegExp]
|
||||||
|
|
||||||
function getComponentName (opts: ?VNodeComponentOptions): ?string {
|
function getComponentName (opts: ?VNodeComponentOptions): ?string {
|
||||||
@ -19,11 +21,11 @@ function matches (pattern: string | RegExp, name: string): boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
function pruneCache (cache, filter) {
|
function pruneCache (cache: VNodeCache, filter: Function) {
|
||||||
for (const key in cache) {
|
for (const key in cache) {
|
||||||
const cachedNode = cache[key]
|
const cachedNode: ?VNode = cache[key]
|
||||||
if (cachedNode) {
|
if (cachedNode) {
|
||||||
const name = getComponentName(cachedNode.componentOptions)
|
const name: ?string = getComponentName(cachedNode.componentOptions)
|
||||||
if (name && !filter(name)) {
|
if (name && !filter(name)) {
|
||||||
pruneCacheEntry(cachedNode)
|
pruneCacheEntry(cachedNode)
|
||||||
cache[key] = null
|
cache[key] = null
|
||||||
@ -32,7 +34,7 @@ function pruneCache (cache, filter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pruneCacheEntry (vnode: ?MountedComponentVNode) {
|
function pruneCacheEntry (vnode: ?VNode) {
|
||||||
if (vnode) {
|
if (vnode) {
|
||||||
if (!vnode.componentInstance._inactive) {
|
if (!vnode.componentInstance._inactive) {
|
||||||
callHook(vnode.componentInstance, 'deactivated')
|
callHook(vnode.componentInstance, 'deactivated')
|
||||||
@ -71,17 +73,17 @@ export default {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
const vnode: VNode = getFirstComponentChild(this.$slots.default)
|
const vnode: VNode = getFirstComponentChild(this.$slots.default)
|
||||||
const componentOptions = vnode && vnode.componentOptions
|
const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
|
||||||
if (componentOptions) {
|
if (componentOptions) {
|
||||||
// check pattern
|
// check pattern
|
||||||
const name = getComponentName(componentOptions)
|
const name: ?string = getComponentName(componentOptions)
|
||||||
if (name && (
|
if (name && (
|
||||||
(this.include && !matches(this.include, name)) ||
|
(this.include && !matches(this.include, name)) ||
|
||||||
(this.exclude && matches(this.exclude, name))
|
(this.exclude && matches(this.exclude, name))
|
||||||
)) {
|
)) {
|
||||||
return vnode
|
return vnode
|
||||||
}
|
}
|
||||||
const key = vnode.key == null
|
const key: ?string = vnode.key == null
|
||||||
// same constructor may get registered as different local components
|
// same constructor may get registered as different local components
|
||||||
// so cid alone is not enough (#3269)
|
// so cid alone is not enough (#3269)
|
||||||
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
|
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
|
||||||
|
@ -4,6 +4,6 @@ export * from './merge-hook'
|
|||||||
export * from './update-listeners'
|
export * from './update-listeners'
|
||||||
export * from './normalize-children'
|
export * from './normalize-children'
|
||||||
|
|
||||||
export function getFirstComponentChild (children: ?Array<any>): ?VNodeWithData {
|
export function getFirstComponentChild (children: ?Array<VNode>): ?VNode {
|
||||||
return children && children.filter(c => c && c.componentOptions)[0]
|
return children && children.filter((c: VNode) => c && c.componentOptions)[0]
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
export function mergeVNodeHook (def: Object, hookKey: string, hook: Function, key: string) {
|
export function mergeVNodeHook (def: Object, hookKey: string, hook: Function, key: string) {
|
||||||
key = key + hookKey
|
key = key + hookKey
|
||||||
const injectedHash = def.__injected || (def.__injected = {})
|
const injectedHash: Object = def.__injected || (def.__injected = {})
|
||||||
if (!injectedHash[key]) {
|
if (!injectedHash[key]) {
|
||||||
injectedHash[key] = true
|
injectedHash[key] = true
|
||||||
const oldHook = def[hookKey]
|
const oldHook: ?Function = def[hookKey]
|
||||||
if (oldHook) {
|
if (oldHook) {
|
||||||
def[hookKey] = function () {
|
def[hookKey] = function () {
|
||||||
oldHook.apply(this, arguments)
|
oldHook.apply(this, arguments)
|
||||||
|
@ -34,35 +34,33 @@ export default {
|
|||||||
props,
|
props,
|
||||||
|
|
||||||
render (h: Function) {
|
render (h: Function) {
|
||||||
const tag = this.tag || this.$vnode.data.tag || 'span'
|
const tag: string = this.tag || this.$vnode.data.tag || 'span'
|
||||||
const map = Object.create(null)
|
const map: Object = Object.create(null)
|
||||||
const prevChildren = this.prevChildren = this.children
|
const prevChildren: Array<VNode> = this.prevChildren = this.children
|
||||||
const rawChildren = this.$slots.default || []
|
const rawChildren: Array<VNode> = this.$slots.default || []
|
||||||
const children = this.children = []
|
const children: Array<VNode> = this.children = []
|
||||||
const transitionData = extractTransitionData(this)
|
const transitionData: Object = extractTransitionData(this)
|
||||||
|
|
||||||
for (let i = 0; i < rawChildren.length; i++) {
|
for (let i = 0; i < rawChildren.length; i++) {
|
||||||
const c = rawChildren[i]
|
const c: VNode = rawChildren[i]
|
||||||
if (c.tag) {
|
if (c.tag) {
|
||||||
if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
|
if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
|
||||||
children.push(c)
|
children.push(c)
|
||||||
map[c.key] = c
|
map[c.key] = c
|
||||||
;(c.data || (c.data = {})).transition = transitionData
|
;(c.data || (c.data = {})).transition = transitionData
|
||||||
} else if (process.env.NODE_ENV !== 'production') {
|
} else if (process.env.NODE_ENV !== 'production') {
|
||||||
const opts = c.componentOptions
|
const opts: ?VNodeComponentOptions = c.componentOptions
|
||||||
const name = opts
|
const name: string = opts ? (opts.Ctor.options.name || opts.tag || '') : c.tag
|
||||||
? (opts.Ctor.options.name || opts.tag)
|
|
||||||
: c.tag
|
|
||||||
warn(`<transition-group> children must be keyed: <${name}>`)
|
warn(`<transition-group> children must be keyed: <${name}>`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevChildren) {
|
if (prevChildren) {
|
||||||
const kept = []
|
const kept: Array<VNode> = []
|
||||||
const removed = []
|
const removed: Array<VNode> = []
|
||||||
for (let i = 0; i < prevChildren.length; i++) {
|
for (let i = 0; i < prevChildren.length; i++) {
|
||||||
const c = prevChildren[i]
|
const c: VNode = prevChildren[i]
|
||||||
c.data.transition = transitionData
|
c.data.transition = transitionData
|
||||||
c.data.pos = c.elm.getBoundingClientRect()
|
c.data.pos = c.elm.getBoundingClientRect()
|
||||||
if (map[c.key]) {
|
if (map[c.key]) {
|
||||||
@ -90,8 +88,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updated () {
|
updated () {
|
||||||
const children = this.prevChildren
|
const children: Array<VNode> = this.prevChildren
|
||||||
const moveClass = this.moveClass || ((this.name || 'v') + '-move')
|
const moveClass: string = this.moveClass || ((this.name || 'v') + '-move')
|
||||||
if (!children.length || !this.hasMove(children[0].elm, moveClass)) {
|
if (!children.length || !this.hasMove(children[0].elm, moveClass)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -104,12 +102,12 @@ export default {
|
|||||||
|
|
||||||
// force reflow to put everything in position
|
// force reflow to put everything in position
|
||||||
const body: any = document.body
|
const body: any = document.body
|
||||||
const f = body.offsetHeight // eslint-disable-line
|
const f: number = body.offsetHeight // eslint-disable-line
|
||||||
|
|
||||||
children.forEach(c => {
|
children.forEach((c: VNode) => {
|
||||||
if (c.data.moved) {
|
if (c.data.moved) {
|
||||||
var el = c.elm
|
var el: any = c.elm
|
||||||
var s = el.style
|
var s: any = el.style
|
||||||
addTransitionClass(el, moveClass)
|
addTransitionClass(el, moveClass)
|
||||||
s.transform = s.WebkitTransform = s.transitionDuration = ''
|
s.transform = s.WebkitTransform = s.transitionDuration = ''
|
||||||
el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {
|
el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {
|
||||||
@ -137,21 +135,21 @@ export default {
|
|||||||
// transition at this very moment, we make a clone of it and remove
|
// transition at this very moment, we make a clone of it and remove
|
||||||
// all other transition classes applied to ensure only the move class
|
// all other transition classes applied to ensure only the move class
|
||||||
// is applied.
|
// is applied.
|
||||||
const clone = el.cloneNode()
|
const clone: HTMLElement = el.cloneNode()
|
||||||
if (el._transitionClasses) {
|
if (el._transitionClasses) {
|
||||||
el._transitionClasses.forEach(cls => { removeClass(clone, cls) })
|
el._transitionClasses.forEach((cls: string) => { removeClass(clone, cls) })
|
||||||
}
|
}
|
||||||
addClass(clone, moveClass)
|
addClass(clone, moveClass)
|
||||||
clone.style.display = 'none'
|
clone.style.display = 'none'
|
||||||
this.$el.appendChild(clone)
|
this.$el.appendChild(clone)
|
||||||
const info = getTransitionInfo(clone)
|
const info: Object = getTransitionInfo(clone)
|
||||||
this.$el.removeChild(clone)
|
this.$el.removeChild(clone)
|
||||||
return (this._hasMove = info.hasTransform)
|
return (this._hasMove = info.hasTransform)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function callPendingCbs (c) {
|
function callPendingCbs (c: VNode) {
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (c.elm._moveCb) {
|
if (c.elm._moveCb) {
|
||||||
c.elm._moveCb()
|
c.elm._moveCb()
|
||||||
@ -162,11 +160,11 @@ function callPendingCbs (c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function recordPosition (c) {
|
function recordPosition (c: VNode) {
|
||||||
c.data.newPos = c.elm.getBoundingClientRect()
|
c.data.newPos = c.elm.getBoundingClientRect()
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyTranslation (c) {
|
function applyTranslation (c: VNode) {
|
||||||
const oldPos = c.data.pos
|
const oldPos = c.data.pos
|
||||||
const newPos = c.data.newPos
|
const newPos = c.data.newPos
|
||||||
const dx = oldPos.left - newPos.left
|
const dx = oldPos.left - newPos.left
|
||||||
|
@ -28,7 +28,7 @@ export const transitionProps = {
|
|||||||
// in case the child is also an abstract component, e.g. <keep-alive>
|
// in case the child is also an abstract component, e.g. <keep-alive>
|
||||||
// we want to recursively retrieve the real component to be rendered
|
// we want to recursively retrieve the real component to be rendered
|
||||||
function getRealChild (vnode: ?VNode): ?VNode {
|
function getRealChild (vnode: ?VNode): ?VNode {
|
||||||
const compOptions = vnode && vnode.componentOptions
|
const compOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
|
||||||
if (compOptions && compOptions.Ctor.options.abstract) {
|
if (compOptions && compOptions.Ctor.options.abstract) {
|
||||||
return getRealChild(getFirstComponentChild(compOptions.children))
|
return getRealChild(getFirstComponentChild(compOptions.children))
|
||||||
} else {
|
} else {
|
||||||
@ -38,27 +38,27 @@ function getRealChild (vnode: ?VNode): ?VNode {
|
|||||||
|
|
||||||
export function extractTransitionData (comp: Component): Object {
|
export function extractTransitionData (comp: Component): Object {
|
||||||
const data = {}
|
const data = {}
|
||||||
const options = comp.$options
|
const options: ComponentOptions = comp.$options
|
||||||
// props
|
// props
|
||||||
for (const key in options.propsData) {
|
for (const key in options.propsData) {
|
||||||
data[key] = comp[key]
|
data[key] = comp[key]
|
||||||
}
|
}
|
||||||
// events.
|
// events.
|
||||||
// extract listeners and pass them directly to the transition methods
|
// extract listeners and pass them directly to the transition methods
|
||||||
const listeners = options._parentListeners
|
const listeners: ?Object = options._parentListeners
|
||||||
for (const key in listeners) {
|
for (const key in listeners) {
|
||||||
data[camelize(key)] = listeners[key].fn
|
data[camelize(key)] = listeners[key].fn
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
function placeholder (h, rawChild) {
|
function placeholder (h: Function, rawChild: VNode): ?VNode {
|
||||||
return /\d-keep-alive$/.test(rawChild.tag)
|
return /\d-keep-alive$/.test(rawChild.tag)
|
||||||
? h('keep-alive')
|
? h('keep-alive')
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasParentTransition (vnode) {
|
function hasParentTransition (vnode: VNode): ?boolean {
|
||||||
while ((vnode = vnode.parent)) {
|
while ((vnode = vnode.parent)) {
|
||||||
if (vnode.data.transition) {
|
if (vnode.data.transition) {
|
||||||
return true
|
return true
|
||||||
@ -66,7 +66,7 @@ function hasParentTransition (vnode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSameChild (child, oldChild) {
|
function isSameChild (child: VNode, oldChild: VNode): boolean {
|
||||||
return oldChild.key === child.key && oldChild.tag === child.tag
|
return oldChild.key === child.key && oldChild.tag === child.tag
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,13 +76,13 @@ export default {
|
|||||||
abstract: true,
|
abstract: true,
|
||||||
|
|
||||||
render (h: Function) {
|
render (h: Function) {
|
||||||
let children = this.$slots.default
|
let children: ?Array<VNode> = this.$slots.default
|
||||||
if (!children) {
|
if (!children) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter out text nodes (possible whitespaces)
|
// filter out text nodes (possible whitespaces)
|
||||||
children = children.filter(c => c.tag)
|
children = children.filter((c: VNode) => c.tag)
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (!children.length) {
|
if (!children.length) {
|
||||||
return
|
return
|
||||||
@ -97,7 +97,7 @@ export default {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const mode = this.mode
|
const mode: string = this.mode
|
||||||
|
|
||||||
// warn invalid mode
|
// warn invalid mode
|
||||||
if (process.env.NODE_ENV !== 'production' &&
|
if (process.env.NODE_ENV !== 'production' &&
|
||||||
@ -108,7 +108,7 @@ export default {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawChild = children[0]
|
const rawChild: VNode = children[0]
|
||||||
|
|
||||||
// if this is a component root node and the component's
|
// if this is a component root node and the component's
|
||||||
// parent container node also has transition, skip.
|
// parent container node also has transition, skip.
|
||||||
@ -118,7 +118,7 @@ export default {
|
|||||||
|
|
||||||
// apply transition data to child
|
// apply transition data to child
|
||||||
// use getRealChild() to ignore abstract components e.g. keep-alive
|
// use getRealChild() to ignore abstract components e.g. keep-alive
|
||||||
const child = getRealChild(rawChild)
|
const child: ?VNode = getRealChild(rawChild)
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (!child) {
|
if (!child) {
|
||||||
return rawChild
|
return rawChild
|
||||||
@ -131,15 +131,15 @@ export default {
|
|||||||
// ensure a key that is unique to the vnode type and to this transition
|
// ensure a key that is unique to the vnode type and to this transition
|
||||||
// component instance. This key will be used to remove pending leaving nodes
|
// component instance. This key will be used to remove pending leaving nodes
|
||||||
// during entering.
|
// during entering.
|
||||||
const id = `__transition-${this._uid}-`
|
const id: string = `__transition-${this._uid}-`
|
||||||
const key = child.key = child.key == null
|
const key: string = child.key = child.key == null
|
||||||
? id + child.tag
|
? id + child.tag
|
||||||
: isPrimitive(child.key)
|
: isPrimitive(child.key)
|
||||||
? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
|
? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
|
||||||
: child.key
|
: child.key
|
||||||
const data = (child.data || (child.data = {})).transition = extractTransitionData(this)
|
const data: Object = (child.data || (child.data = {})).transition = extractTransitionData(this)
|
||||||
const oldRawChild = this._vnode
|
const oldRawChild: VNode = this._vnode
|
||||||
const oldChild: any = getRealChild(oldRawChild)
|
const oldChild: VNode = getRealChild(oldRawChild)
|
||||||
|
|
||||||
// mark v-show
|
// mark v-show
|
||||||
// so that the transition module can hand over the control to the directive
|
// so that the transition module can hand over the control to the directive
|
||||||
@ -150,7 +150,7 @@ export default {
|
|||||||
if (oldChild && oldChild.data && !isSameChild(child, oldChild)) {
|
if (oldChild && oldChild.data && !isSameChild(child, oldChild)) {
|
||||||
// replace old child transition data with fresh one
|
// replace old child transition data with fresh one
|
||||||
// important for dynamic transitions!
|
// important for dynamic transitions!
|
||||||
const oldData = oldChild && (oldChild.data.transition = extend({}, data))
|
const oldData: Object = oldChild && (oldChild.data.transition = extend({}, data))
|
||||||
// handle transition mode
|
// handle transition mode
|
||||||
if (mode === 'out-in') {
|
if (mode === 'out-in') {
|
||||||
// return placeholder node and queue update when leave finishes
|
// return placeholder node and queue update when leave finishes
|
||||||
@ -161,8 +161,8 @@ export default {
|
|||||||
}, key)
|
}, key)
|
||||||
return placeholder(h, rawChild)
|
return placeholder(h, rawChild)
|
||||||
} else if (mode === 'in-out') {
|
} else if (mode === 'in-out') {
|
||||||
var delayedLeave
|
let delayedLeave
|
||||||
var performLeave = () => { delayedLeave() }
|
const performLeave = () => { delayedLeave() }
|
||||||
mergeVNodeHook(data, 'afterEnter', performLeave, key)
|
mergeVNodeHook(data, 'afterEnter', performLeave, key)
|
||||||
mergeVNodeHook(data, 'enterCancelled', performLeave, key)
|
mergeVNodeHook(data, 'enterCancelled', performLeave, key)
|
||||||
mergeVNodeHook(oldData, 'delayLeave', leave => {
|
mergeVNodeHook(oldData, 'delayLeave', leave => {
|
||||||
|
@ -88,7 +88,7 @@ export function whenTransitionEnds (
|
|||||||
) {
|
) {
|
||||||
const { type, timeout, propCount } = getTransitionInfo(el, expectedType)
|
const { type, timeout, propCount } = getTransitionInfo(el, expectedType)
|
||||||
if (!type) return cb()
|
if (!type) return cb()
|
||||||
const event = type === TRANSITION ? transitionEndEvent : animationEndEvent
|
const event: string = type === TRANSITION ? transitionEndEvent : animationEndEvent
|
||||||
let ended = 0
|
let ended = 0
|
||||||
const end = () => {
|
const end = () => {
|
||||||
el.removeEventListener(event, onEnd)
|
el.removeEventListener(event, onEnd)
|
||||||
@ -117,15 +117,15 @@ export function getTransitionInfo (el: Element, expectedType?: ?string): {
|
|||||||
timeout: number;
|
timeout: number;
|
||||||
hasTransform: boolean;
|
hasTransform: boolean;
|
||||||
} {
|
} {
|
||||||
const styles = window.getComputedStyle(el)
|
const styles: any = window.getComputedStyle(el)
|
||||||
const transitioneDelays = styles[transitionProp + 'Delay'].split(', ')
|
const transitioneDelays: Array<string> = styles[transitionProp + 'Delay'].split(', ')
|
||||||
const transitionDurations = styles[transitionProp + 'Duration'].split(', ')
|
const transitionDurations: Array<string> = styles[transitionProp + 'Duration'].split(', ')
|
||||||
const transitionTimeout = getTimeout(transitioneDelays, transitionDurations)
|
const transitionTimeout: number = getTimeout(transitioneDelays, transitionDurations)
|
||||||
const animationDelays = styles[animationProp + 'Delay'].split(', ')
|
const animationDelays: Array<string> = styles[animationProp + 'Delay'].split(', ')
|
||||||
const animationDurations = styles[animationProp + 'Duration'].split(', ')
|
const animationDurations: Array<string> = styles[animationProp + 'Duration'].split(', ')
|
||||||
const animationTimeout = getTimeout(animationDelays, animationDurations)
|
const animationTimeout: number = getTimeout(animationDelays, animationDurations)
|
||||||
|
|
||||||
let type
|
let type: ?string
|
||||||
let timeout = 0
|
let timeout = 0
|
||||||
let propCount = 0
|
let propCount = 0
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
@ -154,7 +154,7 @@ export function getTransitionInfo (el: Element, expectedType?: ?string): {
|
|||||||
: animationDurations.length
|
: animationDurations.length
|
||||||
: 0
|
: 0
|
||||||
}
|
}
|
||||||
const hasTransform =
|
const hasTransform: boolean =
|
||||||
type === TRANSITION &&
|
type === TRANSITION &&
|
||||||
transformRE.test(styles[transitionProp + 'Property'])
|
transformRE.test(styles[transitionProp + 'Property'])
|
||||||
return {
|
return {
|
||||||
|
Loading…
Reference in New Issue
Block a user