diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/vue/src/core/instance/render-helpers | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/vue/src/core/instance/render-helpers')
9 files changed, 370 insertions, 0 deletions
diff --git a/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js b/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js new file mode 100644 index 00000000..5bfc7514 --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js @@ -0,0 +1,22 @@ +/* @flow */ + +import { warn, extend, isPlainObject } from 'core/util/index' + +export function bindObjectListeners (data: any, value: any): VNodeData { + if (value) { + if (!isPlainObject(value)) { + process.env.NODE_ENV !== 'production' && warn( + 'v-on without argument expects an Object value', + this + ) + } else { + const on = data.on = data.on ? extend({}, data.on) : {} + for (const key in value) { + const existing = on[key] + const ours = value[key] + on[key] = existing ? [].concat(existing, ours) : ours + } + } + } + return data +} diff --git a/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js b/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js new file mode 100644 index 00000000..c71dce5c --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js @@ -0,0 +1,60 @@ +/* @flow */ + +import config from 'core/config' + +import { + warn, + isObject, + toObject, + isReservedAttribute +} from 'core/util/index' + +/** + * Runtime helper for merging v-bind="object" into a VNode's data. + */ +export function bindObjectProps ( + data: any, + tag: string, + value: any, + asProp: boolean, + isSync?: boolean +): VNodeData { + if (value) { + if (!isObject(value)) { + process.env.NODE_ENV !== 'production' && warn( + 'v-bind without argument expects an Object or Array value', + this + ) + } else { + if (Array.isArray(value)) { + value = toObject(value) + } + let hash + for (const key in value) { + if ( + key === 'class' || + key === 'style' || + isReservedAttribute(key) + ) { + hash = data + } else { + const type = data.attrs && data.attrs.type + hash = asProp || config.mustUseProp(tag, type, key) + ? data.domProps || (data.domProps = {}) + : data.attrs || (data.attrs = {}) + } + if (!(key in hash)) { + hash[key] = value[key] + + if (isSync) { + const on = data.on || (data.on = {}) + on[`update:${key}`] = function ($event) { + value[key] = $event + } + } + } + } + } + } + return data +} diff --git a/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js b/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js new file mode 100644 index 00000000..c12402b1 --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js @@ -0,0 +1,34 @@ +/* @flow */ + +import config from 'core/config' +import { hyphenate } from 'shared/util' + +function isKeyNotMatch<T> (expect: T | Array<T>, actual: T): boolean { + if (Array.isArray(expect)) { + return expect.indexOf(actual) === -1 + } else { + return expect !== actual + } +} + +/** + * Runtime helper for checking keyCodes from config. + * exposed as Vue.prototype._k + * passing in eventKeyName as last argument separately for backwards compat + */ +export function checkKeyCodes ( + eventKeyCode: number, + key: string, + builtInKeyCode?: number | Array<number>, + eventKeyName?: string, + builtInKeyName?: string | Array<string> +): ?boolean { + const mappedKeyCode = config.keyCodes[key] || builtInKeyCode + if (builtInKeyName && eventKeyName && !config.keyCodes[key]) { + return isKeyNotMatch(builtInKeyName, eventKeyName) + } else if (mappedKeyCode) { + return isKeyNotMatch(mappedKeyCode, eventKeyCode) + } else if (eventKeyName) { + return hyphenate(eventKeyName) !== key + } +} diff --git a/node_modules/vue/src/core/instance/render-helpers/index.js b/node_modules/vue/src/core/instance/render-helpers/index.js new file mode 100644 index 00000000..38414a9a --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/index.js @@ -0,0 +1,30 @@ +/* @flow */ + +import { toNumber, toString, looseEqual, looseIndexOf } from 'shared/util' +import { createTextVNode, createEmptyVNode } from 'core/vdom/vnode' +import { renderList } from './render-list' +import { renderSlot } from './render-slot' +import { resolveFilter } from './resolve-filter' +import { checkKeyCodes } from './check-keycodes' +import { bindObjectProps } from './bind-object-props' +import { renderStatic, markOnce } from './render-static' +import { bindObjectListeners } from './bind-object-listeners' +import { resolveScopedSlots } from './resolve-slots' + +export function installRenderHelpers (target: any) { + target._o = markOnce + target._n = toNumber + target._s = toString + target._l = renderList + target._t = renderSlot + target._q = looseEqual + target._i = looseIndexOf + target._m = renderStatic + target._f = resolveFilter + target._k = checkKeyCodes + target._b = bindObjectProps + target._v = createTextVNode + target._e = createEmptyVNode + target._u = resolveScopedSlots + target._g = bindObjectListeners +} diff --git a/node_modules/vue/src/core/instance/render-helpers/render-list.js b/node_modules/vue/src/core/instance/render-helpers/render-list.js new file mode 100644 index 00000000..abe99db4 --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/render-list.js @@ -0,0 +1,39 @@ +/* @flow */ + +import { isObject, isDef } from 'core/util/index' + +/** + * Runtime helper for rendering v-for lists. + */ +export function renderList ( + val: any, + render: ( + val: any, + keyOrIndex: string | number, + index?: number + ) => VNode +): ?Array<VNode> { + let ret: ?Array<VNode>, i, l, keys, key + if (Array.isArray(val) || typeof val === 'string') { + ret = new Array(val.length) + for (i = 0, l = val.length; i < l; i++) { + ret[i] = render(val[i], i) + } + } else if (typeof val === 'number') { + ret = new Array(val) + for (i = 0; i < val; i++) { + ret[i] = render(i + 1, i) + } + } else if (isObject(val)) { + keys = Object.keys(val) + ret = new Array(keys.length) + for (i = 0, l = keys.length; i < l; i++) { + key = keys[i] + ret[i] = render(val[key], key, i) + } + } + if (isDef(ret)) { + (ret: any)._isVList = true + } + return ret +} diff --git a/node_modules/vue/src/core/instance/render-helpers/render-slot.js b/node_modules/vue/src/core/instance/render-helpers/render-slot.js new file mode 100644 index 00000000..a58daa74 --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/render-slot.js @@ -0,0 +1,50 @@ +/* @flow */ + +import { extend, warn, isObject } from 'core/util/index' + +/** + * Runtime helper for rendering <slot> + */ +export function renderSlot ( + name: string, + fallback: ?Array<VNode>, + props: ?Object, + bindObject: ?Object +): ?Array<VNode> { + const scopedSlotFn = this.$scopedSlots[name] + let nodes + if (scopedSlotFn) { // scoped slot + props = props || {} + if (bindObject) { + if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) { + warn( + 'slot v-bind without argument expects an Object', + this + ) + } + props = extend(extend({}, bindObject), props) + } + nodes = scopedSlotFn(props) || fallback + } else { + const slotNodes = this.$slots[name] + // warn duplicate slot usage + if (slotNodes) { + if (process.env.NODE_ENV !== 'production' && slotNodes._rendered) { + warn( + `Duplicate presence of slot "${name}" found in the same render tree ` + + `- this will likely cause render errors.`, + this + ) + } + slotNodes._rendered = true + } + nodes = slotNodes || fallback + } + + const target = props && props.slot + if (target) { + return this.$createElement('template', { slot: target }, nodes) + } else { + return nodes + } +} diff --git a/node_modules/vue/src/core/instance/render-helpers/render-static.js b/node_modules/vue/src/core/instance/render-helpers/render-static.js new file mode 100644 index 00000000..f56510b3 --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/render-static.js @@ -0,0 +1,60 @@ +/* @flow */ + +/** + * Runtime helper for rendering static trees. + */ +export function renderStatic ( + index: number, + isInFor: boolean +): VNode | Array<VNode> { + const cached = this._staticTrees || (this._staticTrees = []) + let tree = cached[index] + // if has already-rendered static tree and not inside v-for, + // we can reuse the same tree. + if (tree && !isInFor) { + return tree + } + // otherwise, render a fresh tree. + tree = cached[index] = this.$options.staticRenderFns[index].call( + this._renderProxy, + null, + this // for render fns generated for functional component templates + ) + markStatic(tree, `__static__${index}`, false) + return tree +} + +/** + * Runtime helper for v-once. + * Effectively it means marking the node as static with a unique key. + */ +export function markOnce ( + tree: VNode | Array<VNode>, + index: number, + key: string +) { + markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true) + return tree +} + +function markStatic ( + tree: VNode | Array<VNode>, + key: string, + isOnce: boolean +) { + if (Array.isArray(tree)) { + for (let i = 0; i < tree.length; i++) { + if (tree[i] && typeof tree[i] !== 'string') { + markStaticNode(tree[i], `${key}_${i}`, isOnce) + } + } + } else { + markStaticNode(tree, key, isOnce) + } +} + +function markStaticNode (node, key, isOnce) { + node.isStatic = true + node.key = key + node.isOnce = isOnce +} diff --git a/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js b/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js new file mode 100644 index 00000000..08a81e14 --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js @@ -0,0 +1,10 @@ +/* @flow */ + +import { identity, resolveAsset } from 'core/util/index' + +/** + * Runtime helper for resolving filters + */ +export function resolveFilter (id: string): Function { + return resolveAsset(this.$options, 'filters', id, true) || identity +} diff --git a/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js b/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js new file mode 100644 index 00000000..02f007cf --- /dev/null +++ b/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js @@ -0,0 +1,65 @@ +/* @flow */ + +import type VNode from 'core/vdom/vnode' + +/** + * Runtime helper for resolving raw children VNodes into a slot object. + */ +export function resolveSlots ( + children: ?Array<VNode>, + context: ?Component +): { [key: string]: Array<VNode> } { + const slots = {} + if (!children) { + return slots + } + for (let i = 0, l = children.length; i < l; i++) { + const child = children[i] + const data = child.data + // remove slot attribute if the node is resolved as a Vue slot node + if (data && data.attrs && data.attrs.slot) { + delete data.attrs.slot + } + // named slots should only be respected if the vnode was rendered in the + // same context. + if ((child.context === context || child.fnContext === context) && + data && data.slot != null + ) { + const name = data.slot + const slot = (slots[name] || (slots[name] = [])) + if (child.tag === 'template') { + slot.push.apply(slot, child.children || []) + } else { + slot.push(child) + } + } else { + (slots.default || (slots.default = [])).push(child) + } + } + // ignore slots that contains only whitespace + for (const name in slots) { + if (slots[name].every(isWhitespace)) { + delete slots[name] + } + } + return slots +} + +function isWhitespace (node: VNode): boolean { + return (node.isComment && !node.asyncFactory) || node.text === ' ' +} + +export function resolveScopedSlots ( + fns: ScopedSlotsData, // see flow/vnode + res?: Object +): { [key: string]: Function } { + res = res || {} + for (let i = 0; i < fns.length; i++) { + if (Array.isArray(fns[i])) { + resolveScopedSlots(fns[i], res) + } else { + res[fns[i].key] = fns[i].fn + } + } + return res +} |
