This commit is contained in:
Evan You 2016-04-16 17:18:12 -04:00
parent cec2196657
commit 09a4ba84a9
10 changed files with 69 additions and 33 deletions

View File

@ -0,0 +1,4 @@
export function el (el, dir) {
console.log(el)
console.log(dir)
}

View File

@ -1,11 +1,15 @@
import { model } from './model'
import { show } from './show'
import { html } from './html'
import { ref } from './ref'
import { el } from './el'
export const directives = {
model,
show,
html,
ref,
el,
cloak: function () {} // noop
}
@ -13,8 +17,9 @@ export function genDirectives (el) {
const dirs = el.directives
let res = 'directives:['
let hasRuntime = false
for (let i = 0; i < dirs.length; i++) {
let dir = dirs[i]
let i, l, dir
for (i = 0, l = dirs.length; i < l; i++) {
dir = dirs[i]
let gen = directives[dir.name]
if (gen) {
// compile-time directive that manipulates AST
@ -24,6 +29,8 @@ export function genDirectives (el) {
hasRuntime = true
res += `{def:__d__("${dir.name}")${
dir.value ? `,value:(${dir.value})` : ''
}${
dir.arg ? `,arg:"${dir.arg}"` : ''
}${
dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : ''
}},`

View File

@ -0,0 +1,3 @@
export function ref (el, dir) {
el.ref = dir.arg
}

View File

@ -52,24 +52,29 @@ function genData (el) {
let data = '{'
// key
if (el.key) {
data += `key:${el.key},`
}
// slot names
if (el.attrsMap.slot) {
data += `slot:"${el.attrsMap.slot}",`
}
// svg
if (el.svg) {
data += 'svg:true,'
}
// directives first.
// directives may mutate the el's other properties before they are generated.
if (el.directives) {
let dirs = genDirectives(el)
if (dirs) data += dirs + ','
}
// svg
if (el.svg) {
data += 'svg:true,'
}
// key
if (el.key) {
data += `key:${el.key},`
}
// ref
if (el.ref) {
data += `ref:"${el.ref}",`
}
// slot names
if (el.attrsMap.slot) {
data += `slot:"${el.attrsMap.slot}",`
}
// class
if (el.staticClass) {
data += `staticClass:"${el.staticClass}",`

View File

@ -6,6 +6,7 @@ import { addHandler } from '../helpers'
const dirRE = /^v-|^@|^:/
const bindRE = /^:|^v-bind:/
const onRE = /^@|^v-on:/
const argRE = /:(.*)$/
const modifierRE = /\.[^\.]+/g
const mustUsePropsRE = /^(value|selected|checked|muted)$/
const forAliasRE = /([a-zA-Z_][\w]*)\s+(?:in|of)\s+(.*)/
@ -213,12 +214,13 @@ function processStyleBinding (el) {
function processAttributes (el) {
const list = el.attrsList
for (let i = 0; i < list.length; i++) {
let name = list[i].name
let value = list[i].value
let i, l, name, value, arg, modifiers
for (i = 0, l = list.length; i < l; i++) {
name = list[i].name
value = list[i].value
if (dirRE.test(name)) {
// modifiers
const modifiers = parseModifiers(name)
modifiers = parseModifiers(name)
if (modifiers) {
name = name.replace(modifierRE, '')
}
@ -234,9 +236,14 @@ function processAttributes (el) {
addHandler((el.events || (el.events = {})), name, value, modifiers)
} else { // normal directives
name = name.replace(dirRE, '')
// parse arg
if ((arg = name.match(argRE)) && (arg = arg[1])) {
name = name.slice(0, -(arg.length + 1))
}
;(el.directives || (el.directives = [])).push({
name,
value,
arg,
modifiers
})
}

View File

@ -15,7 +15,7 @@ export function parseText (text) {
}
// tag token
const exp = match[1].trim()
tokens.push(`((${exp})==null?'':${exp})`)
tokens.push(`((${exp})==null?'':__s__(${exp}))`)
lastIndex = index + match[0].length
}
if (lastIndex < text.length) {

View File

@ -14,11 +14,17 @@ export function callHook (vm, hook) {
export function initLifecycle (vm) {
const options = vm.$options
// parent
vm.$parent = options.parent
vm.$root = vm.$parent ? vm.$parent.$root : vm
if (vm.$parent) {
vm.$parent.$children.push(vm)
// TODO: handle ref
}
// context & ref
vm._context = options._context
vm._ref = options._renderData && options._renderData.ref
if (vm._ref) {
vm._context.$refs[vm._ref] = vm
}
vm.$children = []
vm.$refs = {}
@ -58,7 +64,10 @@ export function lifecycleMixin (Vue) {
const parent = this.$parent
if (parent && !parent._isBeingDestroyed) {
parent.$children.$remove(this)
// TODO: handle ref
}
// unregister ref
if (this._ref) {
this._context.$refs[this._ref] = undefined
}
// teardown watchers
let i = this._watchers.length

View File

@ -25,6 +25,11 @@ export function renderMixin (Vue) {
return resolveAsset(this.$options, 'directives', id, true)
}
Vue.prototype.__s__ = function (val) {
console.log(val)
return typeof val === 'string' ? val : JSON.stringify(val)
}
Vue.prototype._update = function (vnode) {
if (this._mounted) {
callHook(this, 'beforeUpdate')
@ -42,7 +47,6 @@ export function renderMixin (Vue) {
Vue.prototype._updateFromParent = function (parentData, children, key) {
const oldParentData = this.$options._renderData
this.$options._renderKey = key
this.$options._renderData = parentData
this.$options._renderChildren = children
// update props and listeners
@ -77,7 +81,7 @@ export function renderMixin (Vue) {
Vue.prototype._render = function () {
const prev = renderState.activeInstance
renderState.activeInstance = this
const { render, _renderKey, _renderData, _renderChildren } = this.$options
const { render, _renderData, _renderChildren } = this.$options
// resolve slots. becaues slots are rendered in parent scope,
// we set the activeInstance to parent.
if (_renderChildren) {
@ -85,8 +89,6 @@ export function renderMixin (Vue) {
}
// render self
const vnode = render.call(this)
// set key
vnode.key = _renderKey
// update parent data
if (_renderData) {
mergeParentData(this, vnode.data, _renderData)

View File

@ -1,18 +1,17 @@
import Vue from '../instance/index'
import { callHook } from '../instance/lifecycle'
export default function Component (Ctor, data, parent, children) {
export default function Component (Ctor, data, parent, children, context) {
if (typeof Ctor === 'object') {
Ctor = Vue.extend(Ctor)
}
// return a placeholder vnode
const key = data && data.key
return {
tag: 'component',
key,
key: data && data.key,
data: {
hook: { init, insert, prepatch, destroy },
Ctor, data, parent, children
Ctor, data, parent, children, context
}
}
}
@ -21,9 +20,9 @@ function init (vnode) {
const data = vnode.data
const child = new data.Ctor({
parent: data.parent,
_context: data.context,
_renderData: data.data,
_renderChildren: data.children,
_renderKey: vnode.key
_renderChildren: data.children
})
child.$mount()
data.child = child

View File

@ -17,7 +17,7 @@ export default function createElement (tag, data, children) {
if (isReservedTag(tag)) {
return VNode(tag, data, flatten(children))
} else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {
return Component(Ctor, data, parent, children)
return Component(Ctor, data, parent, children, context)
} else {
if (process.env.NODE_ENV !== 'production' && !data.svg) {
warn(
@ -29,7 +29,7 @@ export default function createElement (tag, data, children) {
return VNode(tag, data, flatten(children && children()))
}
} else {
return Component(tag, data, parent, children)
return Component(tag, data, parent, children, context)
}
}