From 7f143c7402c6a74c9d5b8bef22571cf1f48903fb Mon Sep 17 00:00:00 2001 From: pimlie Date: Sat, 16 May 2020 23:30:31 +0200 Subject: [PATCH] Revert "Revert "fix: also set ssrAppId for first Vue app when ssrAttribute exists"" This reverts commit 305782871547513aba6089d6b323cdc22d5afc14. --- examples/ssr/App.js | 8 +++-- src/shared/mixin.js | 82 ++++++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/examples/ssr/App.js b/examples/ssr/App.js index 453a450f..a9e2092e 100644 --- a/examples/ssr/App.js +++ b/examples/ssr/App.js @@ -66,8 +66,7 @@ export default function createApp () { ] }) - const app = new Vue({ - router, + const App = ({ metaInfo () { return { title: 'Boring Title', @@ -157,6 +156,11 @@ export default function createApp () { ` }) + const app = new Vue({ + router, + render: h => h(App) + }) + const { set } = app.$meta().addApp('custom') set({ bodyAttrs: { class: 'custom-app' }, diff --git a/src/shared/mixin.js b/src/shared/mixin.js index 53d282c6..e39aac51 100644 --- a/src/shared/mixin.js +++ b/src/shared/mixin.js @@ -1,6 +1,7 @@ import { triggerUpdate } from '../client/update' import { isUndefined, isFunction } from '../utils/is-type' import { find } from '../utils/array' +import { getTag } from '../utils/elements' import { rootConfigKey } from './constants' import { hasMetaInfo } from './meta-helpers' import { addNavGuards } from './nav-guards' @@ -21,12 +22,6 @@ export default function createMixin (Vue, options) { const $options = this.$options const devtoolsEnabled = Vue.config.devtools - if (this === $root) { - this.$on('hook:beforeMount', function () { - wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered') - }) - } - Object.defineProperty(this, '_hasMetaInfo', { configurable: true, get () { @@ -39,6 +34,22 @@ export default function createMixin (Vue, options) { } }) + if (this === $root) { + $root.$once('hook:beforeMount', function () { + wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered') + + // In most cases when you have a SSR app it will be the first app thats gonna be + // initiated, if we cant detect the data-server-rendered attribute from Vue but we + // do see our own ssrAttribute then _assume_ the Vue app with appId 1 is the ssr app + // attempted fix for #404 & #562, but we rly need to refactor how we pass appIds from + // ssr to the client + if (!wasServerRendered && $root[rootConfigKey] && $root[rootConfigKey].appId === 1) { + const htmlTag = getTag({}, 'html') + wasServerRendered = htmlTag && htmlTag.hasAttribute(options.ssrAttribute) + } + }) + } + // Add a marker to know if it uses metaInfo // _vnode is used to know that it's attached to a real component // useful if we use some mixin to add some meta tags (like nuxt-i18n) @@ -107,6 +118,7 @@ export default function createMixin (Vue, options) { this.$on('hook:beforeMount', function () { const $root = this[rootKey] + // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported if (wasServerRendered) { @@ -119,35 +131,37 @@ export default function createMixin (Vue, options) { this.$on('hook:mounted', function () { const $root = this[rootKey] - if (!$root[rootConfigKey].initialized) { - // used in triggerUpdate to check if a change was triggered - // during initialization - $root[rootConfigKey].initializing = true - - // refresh meta in nextTick so all child components have loaded - this.$nextTick(function () { - const { tags, metaInfo } = $root.$meta().refresh() - - // After ssr hydration (identifier by tags === false) check - // if initialized was set to null in triggerUpdate. That'd mean - // that during initilazation changes where triggered which need - // to be applied OR a metaInfo watcher was triggered before the - // current hook was called - // (during initialization all changes are blocked) - if (tags === false && $root[rootConfigKey].initialized === null) { - this.$nextTick(() => triggerUpdate(options, $root, 'init')) - } - - $root[rootConfigKey].initialized = true - delete $root[rootConfigKey].initializing - - // add the navigation guards if they havent been added yet - // they are needed for the afterNavigation callback - if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { - addNavGuards($root) - } - }) + if ($root[rootConfigKey].initialized) { + return } + + // used in triggerUpdate to check if a change was triggered + // during initialization + $root[rootConfigKey].initializing = true + + // refresh meta in nextTick so all child components have loaded + this.$nextTick(function () { + const { tags, metaInfo } = $root.$meta().refresh() + + // After ssr hydration (identifier by tags === false) check + // if initialized was set to null in triggerUpdate. That'd mean + // that during initilazation changes where triggered which need + // to be applied OR a metaInfo watcher was triggered before the + // current hook was called + // (during initialization all changes are blocked) + if (tags === false && $root[rootConfigKey].initialized === null) { + this.$nextTick(() => triggerUpdate(options, $root, 'init')) + } + + $root[rootConfigKey].initialized = true + delete $root[rootConfigKey].initializing + + // add the navigation guards if they havent been added yet + // they are needed for the afterNavigation callback + if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { + addNavGuards($root) + } + }) }) // add the navigation guards if requested if (options.refreshOnceOnNavigation) {