modified .gitignore
This commit is contained in:
+27
-9
@@ -15,6 +15,7 @@ import {
|
||||
|
||||
import {
|
||||
resolveAsyncComponent,
|
||||
createAsyncPlaceholder,
|
||||
extractPropsFromVNodeData
|
||||
} from './helpers/index'
|
||||
|
||||
@@ -97,7 +98,7 @@ const hooksToMerge = Object.keys(componentVNodeHooks)
|
||||
|
||||
export function createComponent (
|
||||
Ctor: Class<Component> | Function | Object | void,
|
||||
data?: VNodeData,
|
||||
data: ?VNodeData,
|
||||
context: Component,
|
||||
children: ?Array<VNode>,
|
||||
tag?: string
|
||||
@@ -123,21 +124,30 @@ export function createComponent (
|
||||
}
|
||||
|
||||
// async component
|
||||
let asyncFactory
|
||||
if (isUndef(Ctor.cid)) {
|
||||
Ctor = resolveAsyncComponent(Ctor, baseCtor, context)
|
||||
asyncFactory = Ctor
|
||||
Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context)
|
||||
if (Ctor === undefined) {
|
||||
// return nothing if this is indeed an async component
|
||||
// wait for the callback to trigger parent update.
|
||||
return
|
||||
// return a placeholder node for async component, which is rendered
|
||||
// as a comment node but preserves all the raw information for the node.
|
||||
// the information will be used for async server-rendering and hydration.
|
||||
return createAsyncPlaceholder(
|
||||
asyncFactory,
|
||||
data,
|
||||
context,
|
||||
children,
|
||||
tag
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data = data || {}
|
||||
|
||||
// resolve constructor options in case global mixins are applied after
|
||||
// component constructor creation
|
||||
resolveConstructorOptions(Ctor)
|
||||
|
||||
data = data || {}
|
||||
|
||||
// transform component v-model data into props & events
|
||||
if (isDef(data.model)) {
|
||||
transformModel(Ctor.options, data)
|
||||
@@ -155,12 +165,19 @@ export function createComponent (
|
||||
// child component listeners instead of DOM listeners
|
||||
const listeners = data.on
|
||||
// replace with listeners with .native modifier
|
||||
// so it gets processed during parent component patch.
|
||||
data.on = data.nativeOn
|
||||
|
||||
if (isTrue(Ctor.options.abstract)) {
|
||||
// abstract components do not keep anything
|
||||
// other than props & listeners
|
||||
// other than props & listeners & slot
|
||||
|
||||
// work around flow
|
||||
const slot = data.slot
|
||||
data = {}
|
||||
if (slot) {
|
||||
data.slot = slot
|
||||
}
|
||||
}
|
||||
|
||||
// merge component management hooks onto the placeholder node
|
||||
@@ -171,7 +188,8 @@ export function createComponent (
|
||||
const vnode = new VNode(
|
||||
`vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
|
||||
data, undefined, undefined, undefined, context,
|
||||
{ Ctor, propsData, listeners, tag, children }
|
||||
{ Ctor, propsData, listeners, tag, children },
|
||||
asyncFactory
|
||||
)
|
||||
return vnode
|
||||
}
|
||||
|
||||
+15
-1
@@ -57,10 +57,24 @@ export function _createElement (
|
||||
)
|
||||
return createEmptyVNode()
|
||||
}
|
||||
// object syntax in v-bind
|
||||
if (isDef(data) && isDef(data.is)) {
|
||||
tag = data.is
|
||||
}
|
||||
if (!tag) {
|
||||
// in case of component :is set to falsy value
|
||||
return createEmptyVNode()
|
||||
}
|
||||
// warn against non-primitive key
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
isDef(data) && isDef(data.key) && !isPrimitive(data.key)
|
||||
) {
|
||||
warn(
|
||||
'Avoid using non-primitive value as key, ' +
|
||||
'use string/number value instead.',
|
||||
context
|
||||
)
|
||||
}
|
||||
// support single function children as default scoped slot
|
||||
if (Array.isArray(children) &&
|
||||
typeof children[0] === 'function'
|
||||
@@ -77,7 +91,7 @@ export function _createElement (
|
||||
let vnode, ns
|
||||
if (typeof tag === 'string') {
|
||||
let Ctor
|
||||
ns = config.getTagNamespace(tag)
|
||||
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
|
||||
if (config.isReservedTag(tag)) {
|
||||
// platform built-in elements
|
||||
vnode = new VNode(
|
||||
|
||||
+3
-2
@@ -8,6 +8,7 @@ import { resolveSlots } from '../instance/render-helpers/resolve-slots'
|
||||
import {
|
||||
isDef,
|
||||
camelize,
|
||||
emptyObject,
|
||||
validateProp
|
||||
} from '../util/index'
|
||||
|
||||
@@ -22,7 +23,7 @@ export function createFunctionalComponent (
|
||||
const propOptions = Ctor.options.props
|
||||
if (isDef(propOptions)) {
|
||||
for (const key in propOptions) {
|
||||
props[key] = validateProp(key, propOptions, propsData || {})
|
||||
props[key] = validateProp(key, propOptions, propsData || emptyObject)
|
||||
}
|
||||
} else {
|
||||
if (isDef(data.attrs)) mergeProps(props, data.attrs)
|
||||
@@ -37,7 +38,7 @@ export function createFunctionalComponent (
|
||||
props,
|
||||
children,
|
||||
parent: context,
|
||||
listeners: data.on || {},
|
||||
listeners: data.on || emptyObject,
|
||||
injections: resolveInject(Ctor.options.inject, context),
|
||||
slots: () => resolveSlots(children, context)
|
||||
})
|
||||
|
||||
+2
-1
@@ -1,12 +1,13 @@
|
||||
/* @flow */
|
||||
|
||||
import { isDef } from 'shared/util'
|
||||
import { isAsyncPlaceholder } from './is-async-placeholder'
|
||||
|
||||
export function getFirstComponentChild (children: ?Array<VNode>): ?VNode {
|
||||
if (Array.isArray(children)) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const c = children[i]
|
||||
if (isDef(c) && isDef(c.componentOptions)) {
|
||||
if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -6,3 +6,4 @@ export * from './update-listeners'
|
||||
export * from './normalize-children'
|
||||
export * from './resolve-async-component'
|
||||
export * from './get-first-component-child'
|
||||
export * from './is-async-placeholder'
|
||||
|
||||
+18
@@ -9,12 +9,30 @@ import {
|
||||
isObject
|
||||
} from 'core/util/index'
|
||||
|
||||
import { createEmptyVNode } from 'core/vdom/vnode'
|
||||
|
||||
function ensureCtor (comp, base) {
|
||||
if (comp.__esModule && comp.default) {
|
||||
comp = comp.default
|
||||
}
|
||||
return isObject(comp)
|
||||
? base.extend(comp)
|
||||
: comp
|
||||
}
|
||||
|
||||
export function createAsyncPlaceholder (
|
||||
factory: Function,
|
||||
data: ?VNodeData,
|
||||
context: Component,
|
||||
children: ?Array<VNode>,
|
||||
tag: ?string
|
||||
): VNode {
|
||||
const node = createEmptyVNode()
|
||||
node.asyncFactory = factory
|
||||
node.asyncMeta = { data, context, children, tag }
|
||||
return node
|
||||
}
|
||||
|
||||
export function resolveAsyncComponent (
|
||||
factory: Function,
|
||||
baseCtor: Class<Component>,
|
||||
|
||||
+25
-4
@@ -5,9 +5,11 @@ import { cached, isUndef } from 'shared/util'
|
||||
|
||||
const normalizeEvent = cached((name: string): {
|
||||
name: string,
|
||||
plain: boolean,
|
||||
once: boolean,
|
||||
capture: boolean,
|
||||
passive: boolean
|
||||
passive: boolean,
|
||||
handler?: Function
|
||||
} => {
|
||||
const passive = name.charAt(0) === '&'
|
||||
name = passive ? name.slice(1) : name
|
||||
@@ -15,8 +17,10 @@ const normalizeEvent = cached((name: string): {
|
||||
name = once ? name.slice(1) : name
|
||||
const capture = name.charAt(0) === '!'
|
||||
name = capture ? name.slice(1) : name
|
||||
const plain = !(passive || once || capture)
|
||||
return {
|
||||
name,
|
||||
plain,
|
||||
once,
|
||||
capture,
|
||||
passive
|
||||
@@ -27,8 +31,9 @@ export function createFnInvoker (fns: Function | Array<Function>): Function {
|
||||
function invoker () {
|
||||
const fns = invoker.fns
|
||||
if (Array.isArray(fns)) {
|
||||
for (let i = 0; i < fns.length; i++) {
|
||||
fns[i].apply(null, arguments)
|
||||
const cloned = fns.slice()
|
||||
for (let i = 0; i < cloned.length; i++) {
|
||||
cloned[i].apply(null, arguments)
|
||||
}
|
||||
} else {
|
||||
// return handler return value for single handlers
|
||||
@@ -39,6 +44,11 @@ export function createFnInvoker (fns: Function | Array<Function>): Function {
|
||||
return invoker
|
||||
}
|
||||
|
||||
// #6552
|
||||
function prioritizePlainEvents (a, b) {
|
||||
return a.plain ? -1 : b.plain ? 1 : 0
|
||||
}
|
||||
|
||||
export function updateListeners (
|
||||
on: Object,
|
||||
oldOn: Object,
|
||||
@@ -47,10 +57,13 @@ export function updateListeners (
|
||||
vm: Component
|
||||
) {
|
||||
let name, cur, old, event
|
||||
const toAdd = []
|
||||
let hasModifier = false
|
||||
for (name in on) {
|
||||
cur = on[name]
|
||||
old = oldOn[name]
|
||||
event = normalizeEvent(name)
|
||||
if (!event.plain) hasModifier = true
|
||||
if (isUndef(cur)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
`Invalid handler for event "${event.name}": got ` + String(cur),
|
||||
@@ -60,12 +73,20 @@ export function updateListeners (
|
||||
if (isUndef(cur.fns)) {
|
||||
cur = on[name] = createFnInvoker(cur)
|
||||
}
|
||||
add(event.name, cur, event.once, event.capture, event.passive)
|
||||
event.handler = cur
|
||||
toAdd.push(event)
|
||||
} else if (cur !== old) {
|
||||
old.fns = cur
|
||||
on[name] = old
|
||||
}
|
||||
}
|
||||
if (toAdd.length) {
|
||||
if (hasModifier) toAdd.sort(prioritizePlainEvents)
|
||||
for (let i = 0; i < toAdd.length; i++) {
|
||||
const event = toAdd[i]
|
||||
add(event.name, event.handler, event.once, event.capture, event.passive)
|
||||
}
|
||||
}
|
||||
for (name in oldOn) {
|
||||
if (isUndef(on[name])) {
|
||||
event = normalizeEvent(name)
|
||||
|
||||
+4
-3
@@ -32,10 +32,11 @@ export function registerRef (vnode: VNodeWithData, isRemoval: ?boolean) {
|
||||
}
|
||||
} else {
|
||||
if (vnode.data.refInFor) {
|
||||
if (Array.isArray(refs[key]) && refs[key].indexOf(ref) < 0) {
|
||||
refs[key].push(ref)
|
||||
} else {
|
||||
if (!Array.isArray(refs[key])) {
|
||||
refs[key] = [ref]
|
||||
} else if (refs[key].indexOf(ref) < 0) {
|
||||
// $flow-disable-line
|
||||
refs[key].push(ref)
|
||||
}
|
||||
} else {
|
||||
refs[key] = ref
|
||||
|
||||
+103
-42
@@ -6,8 +6,6 @@
|
||||
*
|
||||
* modified by Evan You (@yyx990803)
|
||||
*
|
||||
|
||||
/*
|
||||
* Not type-checking this because this file is perf-critical and the cost
|
||||
* of making flow understand it is not worth it.
|
||||
*/
|
||||
@@ -17,6 +15,7 @@ import config from '../config'
|
||||
import { SSR_ATTR } from 'shared/constants'
|
||||
import { registerRef } from './modules/ref'
|
||||
import { activeInstance } from '../instance/lifecycle'
|
||||
import { isTextInputType } from 'web/util/element'
|
||||
|
||||
import {
|
||||
warn,
|
||||
@@ -33,22 +32,27 @@ const hooks = ['create', 'activate', 'update', 'remove', 'destroy']
|
||||
|
||||
function sameVnode (a, b) {
|
||||
return (
|
||||
a.key === b.key &&
|
||||
a.tag === b.tag &&
|
||||
a.isComment === b.isComment &&
|
||||
isDef(a.data) === isDef(b.data) &&
|
||||
sameInputType(a, b)
|
||||
a.key === b.key && (
|
||||
(
|
||||
a.tag === b.tag &&
|
||||
a.isComment === b.isComment &&
|
||||
isDef(a.data) === isDef(b.data) &&
|
||||
sameInputType(a, b)
|
||||
) || (
|
||||
isTrue(a.isAsyncPlaceholder) &&
|
||||
a.asyncFactory === b.asyncFactory &&
|
||||
isUndef(b.asyncFactory.error)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// Some browsers do not support dynamically changing type for <input>
|
||||
// so they need to be treated as different nodes
|
||||
function sameInputType (a, b) {
|
||||
if (a.tag !== 'input') return true
|
||||
let i
|
||||
const typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type
|
||||
const typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type
|
||||
return typeA === typeB
|
||||
return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
|
||||
}
|
||||
|
||||
function createKeyToOldIdx (children, beginIdx, endIdx) {
|
||||
@@ -397,10 +401,11 @@ export function createPatchFunction (backend) {
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
} else {
|
||||
if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
|
||||
idxInOld = isDef(newStartVnode.key) ? oldKeyToIdx[newStartVnode.key] : null
|
||||
idxInOld = isDef(newStartVnode.key)
|
||||
? oldKeyToIdx[newStartVnode.key]
|
||||
: findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
|
||||
if (isUndef(idxInOld)) { // New element
|
||||
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm)
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
} else {
|
||||
elmToMove = oldCh[idxInOld]
|
||||
/* istanbul ignore if */
|
||||
@@ -413,14 +418,13 @@ export function createPatchFunction (backend) {
|
||||
if (sameVnode(elmToMove, newStartVnode)) {
|
||||
patchVnode(elmToMove, newStartVnode, insertedVnodeQueue)
|
||||
oldCh[idxInOld] = undefined
|
||||
canMove && nodeOps.insertBefore(parentElm, newStartVnode.elm, oldStartVnode.elm)
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
canMove && nodeOps.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm)
|
||||
} else {
|
||||
// same key but different element. treat as new element
|
||||
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm)
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
}
|
||||
}
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
}
|
||||
}
|
||||
if (oldStartIdx > oldEndIdx) {
|
||||
@@ -431,10 +435,29 @@ export function createPatchFunction (backend) {
|
||||
}
|
||||
}
|
||||
|
||||
function findIdxInOld (node, oldCh, start, end) {
|
||||
for (let i = start; i < end; i++) {
|
||||
const c = oldCh[i]
|
||||
if (isDef(c) && sameVnode(node, c)) return i
|
||||
}
|
||||
}
|
||||
|
||||
function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) {
|
||||
if (oldVnode === vnode) {
|
||||
return
|
||||
}
|
||||
|
||||
const elm = vnode.elm = oldVnode.elm
|
||||
|
||||
if (isTrue(oldVnode.isAsyncPlaceholder)) {
|
||||
if (isDef(vnode.asyncFactory.resolved)) {
|
||||
hydrate(oldVnode.elm, vnode, insertedVnodeQueue)
|
||||
} else {
|
||||
vnode.isAsyncPlaceholder = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// reuse element for static trees.
|
||||
// note we only do this if the vnode is cloned -
|
||||
// if the new node is not cloned it means the render functions have been
|
||||
@@ -444,16 +467,16 @@ export function createPatchFunction (backend) {
|
||||
vnode.key === oldVnode.key &&
|
||||
(isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
|
||||
) {
|
||||
vnode.elm = oldVnode.elm
|
||||
vnode.componentInstance = oldVnode.componentInstance
|
||||
return
|
||||
}
|
||||
|
||||
let i
|
||||
const data = vnode.data
|
||||
if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
|
||||
i(oldVnode, vnode)
|
||||
}
|
||||
const elm = vnode.elm = oldVnode.elm
|
||||
|
||||
const oldCh = oldVnode.children
|
||||
const ch = vnode.children
|
||||
if (isDef(data) && isPatchable(vnode)) {
|
||||
@@ -498,6 +521,11 @@ export function createPatchFunction (backend) {
|
||||
|
||||
// Note: this is a browser-only function so we can assume elms are DOM nodes.
|
||||
function hydrate (elm, vnode, insertedVnodeQueue) {
|
||||
if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
|
||||
vnode.elm = elm
|
||||
vnode.isAsyncPlaceholder = true
|
||||
return true
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!assertNodeMatch(elm, vnode)) {
|
||||
return false
|
||||
@@ -519,27 +547,46 @@ export function createPatchFunction (backend) {
|
||||
if (!elm.hasChildNodes()) {
|
||||
createChildren(vnode, children, insertedVnodeQueue)
|
||||
} else {
|
||||
let childrenMatch = true
|
||||
let childNode = elm.firstChild
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue)) {
|
||||
childrenMatch = false
|
||||
break
|
||||
// v-html and domProps: innerHTML
|
||||
if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
|
||||
if (i !== elm.innerHTML) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
typeof console !== 'undefined' &&
|
||||
!bailed
|
||||
) {
|
||||
bailed = true
|
||||
console.warn('Parent: ', elm)
|
||||
console.warn('server innerHTML: ', i)
|
||||
console.warn('client innerHTML: ', elm.innerHTML)
|
||||
}
|
||||
return false
|
||||
}
|
||||
childNode = childNode.nextSibling
|
||||
}
|
||||
// if childNode is not null, it means the actual childNodes list is
|
||||
// longer than the virtual children list.
|
||||
if (!childrenMatch || childNode) {
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
typeof console !== 'undefined' &&
|
||||
!bailed
|
||||
) {
|
||||
bailed = true
|
||||
console.warn('Parent: ', elm)
|
||||
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)
|
||||
} else {
|
||||
// iterate and compare children lists
|
||||
let childrenMatch = true
|
||||
let childNode = elm.firstChild
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue)) {
|
||||
childrenMatch = false
|
||||
break
|
||||
}
|
||||
childNode = childNode.nextSibling
|
||||
}
|
||||
// if childNode is not null, it means the actual childNodes list is
|
||||
// longer than the virtual children list.
|
||||
if (!childrenMatch || childNode) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
typeof console !== 'undefined' &&
|
||||
!bailed
|
||||
) {
|
||||
bailed = true
|
||||
console.warn('Parent: ', elm)
|
||||
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,14 +677,28 @@ export function createPatchFunction (backend) {
|
||||
// component root element replaced.
|
||||
// update parent placeholder node element, recursively
|
||||
let ancestor = vnode.parent
|
||||
const patchable = isPatchable(vnode)
|
||||
while (ancestor) {
|
||||
ancestor.elm = vnode.elm
|
||||
ancestor = ancestor.parent
|
||||
}
|
||||
if (isPatchable(vnode)) {
|
||||
for (let i = 0; i < cbs.create.length; ++i) {
|
||||
cbs.create[i](emptyNode, vnode.parent)
|
||||
for (let i = 0; i < cbs.destroy.length; ++i) {
|
||||
cbs.destroy[i](ancestor)
|
||||
}
|
||||
ancestor.elm = vnode.elm
|
||||
if (patchable) {
|
||||
for (let i = 0; i < cbs.create.length; ++i) {
|
||||
cbs.create[i](emptyNode, ancestor)
|
||||
}
|
||||
// #6513
|
||||
// invoke insert hooks that may have been merged by create hooks.
|
||||
// e.g. for directives that uses the "inserted" hook.
|
||||
const insert = ancestor.data.hook.insert
|
||||
if (insert.merged) {
|
||||
// start at index 1 to avoid re-invoking component mounted hook
|
||||
for (let i = 1; i < insert.fns.length; i++) {
|
||||
insert.fns[i]()
|
||||
}
|
||||
}
|
||||
}
|
||||
ancestor = ancestor.parent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-7
@@ -19,6 +19,10 @@ export default class VNode {
|
||||
isComment: boolean; // empty comment placeholder?
|
||||
isCloned: boolean; // is a cloned node?
|
||||
isOnce: boolean; // is a v-once node?
|
||||
asyncFactory: Function | void; // async component factory function
|
||||
asyncMeta: Object | void;
|
||||
isAsyncPlaceholder: boolean;
|
||||
ssrContext: Object | void;
|
||||
|
||||
constructor (
|
||||
tag?: string,
|
||||
@@ -27,7 +31,8 @@ export default class VNode {
|
||||
text?: string,
|
||||
elm?: Node,
|
||||
context?: Component,
|
||||
componentOptions?: VNodeComponentOptions
|
||||
componentOptions?: VNodeComponentOptions,
|
||||
asyncFactory?: Function
|
||||
) {
|
||||
this.tag = tag
|
||||
this.data = data
|
||||
@@ -47,6 +52,9 @@ export default class VNode {
|
||||
this.isComment = false
|
||||
this.isCloned = false
|
||||
this.isOnce = false
|
||||
this.asyncFactory = asyncFactory
|
||||
this.asyncMeta = undefined
|
||||
this.isAsyncPlaceholder = false
|
||||
}
|
||||
|
||||
// DEPRECATED: alias for componentInstance for backwards compat.
|
||||
@@ -56,9 +64,9 @@ export default class VNode {
|
||||
}
|
||||
}
|
||||
|
||||
export const createEmptyVNode = () => {
|
||||
export const createEmptyVNode = (text: string = '') => {
|
||||
const node = new VNode()
|
||||
node.text = ''
|
||||
node.text = text
|
||||
node.isComment = true
|
||||
return node
|
||||
}
|
||||
@@ -71,7 +79,7 @@ export function createTextVNode (val: string | number) {
|
||||
// used for static nodes and slot nodes because they may be reused across
|
||||
// multiple renders, cloning them avoids errors when DOM manipulations rely
|
||||
// on their elm reference.
|
||||
export function cloneVNode (vnode: VNode): VNode {
|
||||
export function cloneVNode (vnode: VNode, deep?: boolean): VNode {
|
||||
const cloned = new VNode(
|
||||
vnode.tag,
|
||||
vnode.data,
|
||||
@@ -79,21 +87,25 @@ export function cloneVNode (vnode: VNode): VNode {
|
||||
vnode.text,
|
||||
vnode.elm,
|
||||
vnode.context,
|
||||
vnode.componentOptions
|
||||
vnode.componentOptions,
|
||||
vnode.asyncFactory
|
||||
)
|
||||
cloned.ns = vnode.ns
|
||||
cloned.isStatic = vnode.isStatic
|
||||
cloned.key = vnode.key
|
||||
cloned.isComment = vnode.isComment
|
||||
cloned.isCloned = true
|
||||
if (deep && vnode.children) {
|
||||
cloned.children = cloneVNodes(vnode.children)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
export function cloneVNodes (vnodes: Array<VNode>): Array<VNode> {
|
||||
export function cloneVNodes (vnodes: Array<VNode>, deep?: boolean): Array<VNode> {
|
||||
const len = vnodes.length
|
||||
const res = new Array(len)
|
||||
for (let i = 0; i < len; i++) {
|
||||
res[i] = cloneVNode(vnodes[i])
|
||||
res[i] = cloneVNode(vnodes[i], deep)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user