Explorar o código

tweak ssr async resolve, revert $forceUpdate change

Evan You %!s(int64=10) %!d(string=hai) anos
pai
achega
498448284a

+ 2 - 2
src/core/instance/lifecycle.js

@@ -39,7 +39,7 @@ export function lifecycleMixin (Vue) {
         }
       }
     }
-    this.renderStaticTrees()
+    this._renderStaticTrees()
     this._watcher = new Watcher(this, this._render, this._update)
     this._update(this._watcher.value)
     this._mounted = true
@@ -110,7 +110,7 @@ export function lifecycleMixin (Vue) {
   }
 
   Vue.prototype.$forceUpdate = function () {
-    this._update(this._render())
+    this._watcher.update()
   }
 
   Vue.prototype.$destroy = function () {

+ 32 - 24
src/core/vdom/create-component.js

@@ -31,15 +31,17 @@ export function createComponent (Ctor, data, parent, children, context) {
     if (Ctor.resolved) {
       Ctor = Ctor.resolved
     } else {
-      const resolved = resolveAsyncComponent(Ctor, () => {
+      Ctor = resolveAsyncComponent(Ctor, () => {
         // it's ok to queue this on every render because
-        // $forceUpdate is buffered.
+        // $forceUpdate is buffered. this is only called
+        // if the
         parent.$forceUpdate()
       })
-      if (!resolved || !resolved.cid) {
+      if (!Ctor) {
+        // return nothing if this is indeed an async component
+        // wait for the callback to trigger parent update.
         return
       }
-      Ctor = resolved
     }
   }
 
@@ -120,27 +122,33 @@ function resolveAsyncComponent (factory, cb) {
   } else {
     factory.requested = true
     const cbs = factory.pendingCallbacks = [cb]
-    factory.resolved = factory(function resolve (res) {
-      if (isObject(res)) {
-        res = Vue.extend(res)
+    let sync = true
+    factory(
+      // resolve
+      res => {
+        if (isObject(res)) {
+          res = Vue.extend(res)
+        }
+        // cache resolved
+        factory.resolved = res
+        // invoke callbacks only if this is not a synchronous resolve
+        // (async resolves are shimmed as synchronous during SSR)
+        if (!sync) {
+          for (let i = 0, l = cbs.length; i < l; i++) {
+            cbs[i](res)
+          }
+        }
+      },
+      // reject
+      reason => {
+        process.env.NODE_ENV !== 'production' && warn(
+          `Failed to resolve async component: ${factory}` +
+          (reason ? `\nReason: ${reason}` : '')
+        )
       }
-      // cache resolved
-      factory.resolved = res
-
-      // invoke callbacks
-      for (let i = 0, l = cbs.length; i < l; i++) {
-        cbs[i](res)
-        // Reset pending callbacks
-        factory.pendingCallbacks = []
-      }
-
-      return res
-    }, function reject (reason) {
-      process.env.NODE_ENV !== 'production' && warn(
-        `Failed to resolve async component: ${factory}` +
-        (reason ? `\nReason: ${reason}` : '')
-      )
-    })
+    )
+    sync = false
+    // return in case resolved synchronously
     return factory.resolved
   }
 }

+ 5 - 5
test/ssr/ssr.string.spec.js

@@ -134,7 +134,7 @@ describe('SSR: renderToString', () => {
       `,
       components: {
         testAsync (resolve) {
-          return resolve({
+          resolve({
             render () {
               return this.$createElement('span', { class: ['b'] }, 'testAsync')
             }
@@ -149,7 +149,7 @@ describe('SSR: renderToString', () => {
       template: '<test-async></test-async>',
       components: {
         testAsync (resolve) {
-          return resolve({
+          resolve({
             render () {
               return this.$createElement('span', { class: ['b'] }, 'testAsync')
             }
@@ -176,14 +176,14 @@ describe('SSR: renderToString', () => {
 
           options.components = {
             testSubAsync (resolve) {
-              return resolve({
+              resolve({
                 render () {
                   return this.$createElement('div', { class: ['c'] }, 'testSubAsync')
                 }
               })
             }
           }
-          return resolve(options)
+          resolve(options)
         }
       }
     })).toContain(
@@ -216,7 +216,7 @@ describe('SSR: renderToString', () => {
           }
         },
         testAsync (resolve) {
-          return resolve({
+          resolve({
             render () {
               return this.$createElement('span', { class: ['b'] }, 'testAsync')
             }