mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-25 11:40:33 +03:00
fix: try to detect global mixins adding meta info (#467)
* feat: try to detect global mixins adding meta info * fix: add find polyfill for ie * fix: only detect global mixins when Vue.devtools: true
This commit is contained in:
+20
-2
@@ -1,5 +1,6 @@
|
|||||||
import { triggerUpdate } from '../client/update'
|
import { triggerUpdate } from '../client/update'
|
||||||
import { isUndefined, isFunction } from '../utils/is-type'
|
import { isUndefined, isFunction } from '../utils/is-type'
|
||||||
|
import { find } from '../utils/array'
|
||||||
import { ensuredPush } from '../utils/ensure'
|
import { ensuredPush } from '../utils/ensure'
|
||||||
import { rootConfigKey } from './constants'
|
import { rootConfigKey } from './constants'
|
||||||
import { hasMetaInfo } from './meta-helpers'
|
import { hasMetaInfo } from './meta-helpers'
|
||||||
@@ -18,12 +19,13 @@ export default function createMixin (Vue, options) {
|
|||||||
const rootKey = '$root'
|
const rootKey = '$root'
|
||||||
const $root = this[rootKey]
|
const $root = this[rootKey]
|
||||||
const $options = this.$options
|
const $options = this.$options
|
||||||
|
const devtoolsEnabled = Vue.config.devtools
|
||||||
|
|
||||||
Object.defineProperty(this, '_hasMetaInfo', {
|
Object.defineProperty(this, '_hasMetaInfo', {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
get () {
|
get () {
|
||||||
// Show deprecation warning once when devtools enabled
|
// Show deprecation warning once when devtools enabled
|
||||||
if (Vue.config.devtools && !$root[rootConfigKey].deprecationWarningShown) {
|
if (devtoolsEnabled && !$root[rootConfigKey].deprecationWarningShown) {
|
||||||
warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead')
|
warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead')
|
||||||
$root[rootConfigKey].deprecationWarningShown = true
|
$root[rootConfigKey].deprecationWarningShown = true
|
||||||
}
|
}
|
||||||
@@ -41,6 +43,17 @@ export default function createMixin (Vue, options) {
|
|||||||
if (!$root[rootConfigKey]) {
|
if (!$root[rootConfigKey]) {
|
||||||
$root[rootConfigKey] = { appId }
|
$root[rootConfigKey] = { appId }
|
||||||
appId++
|
appId++
|
||||||
|
|
||||||
|
if (devtoolsEnabled && $root.$options[options.keyName]) {
|
||||||
|
// use nextTick so the children should be added to $root
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// find the first child that lists fnOptions
|
||||||
|
const child = find($root.$children, c => c.$vnode && c.$vnode.fnOptions)
|
||||||
|
if (child && child.$vnode.fnOptions[options.keyName]) {
|
||||||
|
warn(`VueMeta has detected a possible global mixin which adds a ${options.keyName} property to all Vue components on the page. This could cause severe performance issues. If possible, use $meta().addApp to add meta information instead`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// to speed up updates we keep track of branches which have a component with vue-meta info defined
|
// to speed up updates we keep track of branches which have a component with vue-meta info defined
|
||||||
@@ -83,14 +96,18 @@ export default function createMixin (Vue, options) {
|
|||||||
$root[rootConfigKey].initialized = this.$isServer
|
$root[rootConfigKey].initialized = this.$isServer
|
||||||
|
|
||||||
if (!$root[rootConfigKey].initialized) {
|
if (!$root[rootConfigKey].initialized) {
|
||||||
|
if (!$root[rootConfigKey].initializedSsr) {
|
||||||
|
$root[rootConfigKey].initializedSsr = true
|
||||||
|
|
||||||
ensuredPush($options, 'beforeMount', function () {
|
ensuredPush($options, 'beforeMount', function () {
|
||||||
const $root = this[rootKey]
|
const $root = this
|
||||||
// if this Vue-app was server rendered, set the appId to 'ssr'
|
// if this Vue-app was server rendered, set the appId to 'ssr'
|
||||||
// only one SSR app per page is supported
|
// only one SSR app per page is supported
|
||||||
if ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) {
|
if ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) {
|
||||||
$root[rootConfigKey].appId = options.ssrAppId
|
$root[rootConfigKey].appId = options.ssrAppId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// we use the mounted hook here as on page load
|
// we use the mounted hook here as on page load
|
||||||
ensuredPush($options, 'mounted', function () {
|
ensuredPush($options, 'mounted', function () {
|
||||||
@@ -155,6 +172,7 @@ export default function createMixin (Vue, options) {
|
|||||||
if (!this.$parent || !hasMetaInfo(this)) {
|
if (!this.$parent || !hasMetaInfo(this)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
delete this._hasMetaInfo
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (!options.waitOnDestroyed || !this.$el || !this.$el.offsetParent) {
|
if (!options.waitOnDestroyed || !this.$el || !this.$el.offsetParent) {
|
||||||
|
|||||||
@@ -11,6 +11,19 @@
|
|||||||
// which means the polyfills are removed for other build formats
|
// which means the polyfills are removed for other build formats
|
||||||
const polyfill = process.env.NODE_ENV === 'test'
|
const polyfill = process.env.NODE_ENV === 'test'
|
||||||
|
|
||||||
|
export function find (array, predicate, thisArg) {
|
||||||
|
if (polyfill && !Array.prototype.find) {
|
||||||
|
// idx needs to be a Number, for..in returns string
|
||||||
|
for (let idx = 0; idx < array.length; idx++) {
|
||||||
|
if (predicate.call(thisArg, array[idx], idx, array)) {
|
||||||
|
return array[idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return array.find(predicate, thisArg)
|
||||||
|
}
|
||||||
|
|
||||||
export function findIndex (array, predicate, thisArg) {
|
export function findIndex (array, predicate, thisArg) {
|
||||||
if (polyfill && !Array.prototype.findIndex) {
|
if (polyfill && !Array.prototype.findIndex) {
|
||||||
// idx needs to be a Number, for..in returns string
|
// idx needs to be a Number, for..in returns string
|
||||||
|
|||||||
+12
-1
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @jest-environment node
|
* @jest-environment node
|
||||||
*/
|
*/
|
||||||
import { findIndex, includes, toArray } from '../../src/utils/array'
|
import { find, findIndex, includes, toArray } from '../../src/utils/array'
|
||||||
import { ensureIsArray } from '../../src/utils/ensure'
|
import { ensureIsArray } from '../../src/utils/ensure'
|
||||||
import { hasGlobalWindowFn } from '../../src/utils/window'
|
import { hasGlobalWindowFn } from '../../src/utils/window'
|
||||||
|
|
||||||
@@ -29,6 +29,17 @@ describe('shared', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
/* eslint-disable no-extend-native */
|
/* eslint-disable no-extend-native */
|
||||||
|
test('find polyfill', () => {
|
||||||
|
const _find = Array.prototype.find
|
||||||
|
Array.prototype.find = false
|
||||||
|
|
||||||
|
const arr = [1, 2, 3]
|
||||||
|
expect(find(arr, (v, i) => i === 0)).toBe(1)
|
||||||
|
expect(find(arr, (v, i) => i === 3)).toBe(undefined)
|
||||||
|
|
||||||
|
Array.prototype.find = _find
|
||||||
|
})
|
||||||
|
|
||||||
test('findIndex polyfill', () => {
|
test('findIndex polyfill', () => {
|
||||||
const _findIndex = Array.prototype.findIndex
|
const _findIndex = Array.prototype.findIndex
|
||||||
Array.prototype.findIndex = false
|
Array.prototype.findIndex = false
|
||||||
|
|||||||
Reference in New Issue
Block a user