Evan You 10 лет назад
Родитель
Сommit
8218eae1f9

+ 1 - 1
src/compiler/codegen/index.js

@@ -103,7 +103,7 @@ function genNode (node) {
 
 
 function genText (text) {
 function genText (text) {
   return text.expression
   return text.expression
-    ? `(${text.expression}==null?'':String(${text.expression}))`
+    ? `(${text.expression})`
     : JSON.stringify(text.text)
     : JSON.stringify(text.text)
 }
 }
 
 

+ 2 - 1
src/compiler/parser/text-parser.js

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

+ 39 - 9
src/runtime/instance/render.js

@@ -1,5 +1,5 @@
 import Watcher from '../observer/watcher'
 import Watcher from '../observer/watcher'
-import { query, resolveAsset, hyphenate } from '../util/index'
+import { query, resolveAsset, hyphenate, hasOwn } from '../util/index'
 import { createElement, patch } from '../vdom/index'
 import { createElement, patch } from '../vdom/index'
 import { callHook } from './lifecycle'
 import { callHook } from './lifecycle'
 
 
@@ -11,18 +11,28 @@ export function initRender (vm) {
   vm._vnode = null
   vm._vnode = null
   vm._mounted = false
   vm._mounted = false
   vm._renderData = vm.$options._renderData
   vm._renderData = vm.$options._renderData
-  vm.$slots = resolveSlots(vm.$options._renderChildren)
+  vm.$slots = {}
+  // props are set in initState
+  resolveSlots(vm, vm.$options._renderChildren)
   const el = vm.$options.el
   const el = vm.$options.el
   if (el) {
   if (el) {
     vm.$mount(el)
     vm.$mount(el)
   }
   }
 }
 }
 
 
-function resolveSlots (children) {
-  const slots = {
-    default: children
+export function setProps (vm, data) {
+  const attrs = (data && data.attrs) || {}
+  const props = vm.$options.props
+  if (props) {
+    for (let key in props) {
+      vm[key] = attrs[key]
+    }
   }
   }
+}
+
+function resolveSlots (vm, children) {
   if (children) {
   if (children) {
+    const slots = { default: children }
     let i = children.length
     let i = children.length
     let name, child
     let name, child
     while (i--) {
     while (i--) {
@@ -32,8 +42,24 @@ function resolveSlots (children) {
         children.splice(i, 1)
         children.splice(i, 1)
       }
       }
     }
     }
+    vm.$slots = slots
+  }
+}
+
+function mergeParentData (vm, data, parentData) {
+  // attrs
+  if (parentData.attrs) {
+    const props = vm.$options.props
+    for (let key in parentData.attrs) {
+      if (!hasOwn(props, key)) {
+        data.attrs[key] = parentData.attrs[key]
+      }
+    }
+  }
+  // directives
+  if (parentData.directives) {
+    data.directives = parentData.directives.conact(data.directives || [])
   }
   }
-  return slots
 }
 }
 
 
 export function renderMixin (Vue) {
 export function renderMixin (Vue) {
@@ -56,13 +82,14 @@ export function renderMixin (Vue) {
 
 
   Vue.prototype._tryUpdate = function (data, children) {
   Vue.prototype._tryUpdate = function (data, children) {
     this._renderData = data
     this._renderData = data
-    this.$slots = resolveSlots(children)
     if (children) {
     if (children) {
+      resolveSlots(this, children)
       this.$forceUpdate()
       this.$forceUpdate()
       return
       return
     }
     }
     // check props
     // check props
     if (data && data.attrs) {
     if (data && data.attrs) {
+      setProps(this, data)
       for (let key in this.$options.props) {
       for (let key in this.$options.props) {
         let oldVal = this[key]
         let oldVal = this[key]
         let newVal = data.attrs[key] || data.attrs[hyphenate(key)]
         let newVal = data.attrs[key] || data.attrs[hyphenate(key)]
@@ -77,8 +104,11 @@ export function renderMixin (Vue) {
     const prev = renderState.activeInstance
     const prev = renderState.activeInstance
     renderState.activeInstance = this
     renderState.activeInstance = this
     const vnode = this.$options.render.call(this)
     const vnode = this.$options.render.call(this)
-    // merge parent data
-    // TODO
+    const data = vnode.data
+    const parentData = this._renderData
+    if (parentData) {
+      mergeParentData(this, data, parentData)
+    }
     renderState.activeInstance = prev
     renderState.activeInstance = prev
     return vnode
     return vnode
   }
   }

+ 2 - 5
src/runtime/instance/state.js

@@ -1,6 +1,7 @@
 import Watcher from '../observer/watcher'
 import Watcher from '../observer/watcher'
 import Dep from '../observer/dep'
 import Dep from '../observer/dep'
 import { observe } from '../observer/index'
 import { observe } from '../observer/index'
+import { setProps } from './render'
 
 
 import {
 import {
   warn,
   warn,
@@ -12,17 +13,13 @@ import {
 
 
 export function initState (vm) {
 export function initState (vm) {
   vm._watchers = []
   vm._watchers = []
-  initProps(vm)
+  setProps(vm, vm.$options._renderData)
   initData(vm)
   initData(vm)
   initComputed(vm)
   initComputed(vm)
   initMethods(vm)
   initMethods(vm)
   initWatch(vm)
   initWatch(vm)
 }
 }
 
 
-function initProps (vm) {
-  // TODO
-}
-
 function initData (vm) {
 function initData (vm) {
   var data = vm.$options.data
   var data = vm.$options.data
   data = vm._data = typeof data === 'function'
   data = vm._data = typeof data === 'function'