mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-22 18:50:34 +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:
+27
-9
@@ -1,5 +1,6 @@
|
||||
import { triggerUpdate } from '../client/update'
|
||||
import { isUndefined, isFunction } from '../utils/is-type'
|
||||
import { find } from '../utils/array'
|
||||
import { ensuredPush } from '../utils/ensure'
|
||||
import { rootConfigKey } from './constants'
|
||||
import { hasMetaInfo } from './meta-helpers'
|
||||
@@ -18,12 +19,13 @@ export default function createMixin (Vue, options) {
|
||||
const rootKey = '$root'
|
||||
const $root = this[rootKey]
|
||||
const $options = this.$options
|
||||
const devtoolsEnabled = Vue.config.devtools
|
||||
|
||||
Object.defineProperty(this, '_hasMetaInfo', {
|
||||
configurable: true,
|
||||
get () {
|
||||
// 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')
|
||||
$root[rootConfigKey].deprecationWarningShown = true
|
||||
}
|
||||
@@ -41,6 +43,17 @@ export default function createMixin (Vue, options) {
|
||||
if (!$root[rootConfigKey]) {
|
||||
$root[rootConfigKey] = { 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
|
||||
@@ -83,14 +96,18 @@ export default function createMixin (Vue, options) {
|
||||
$root[rootConfigKey].initialized = this.$isServer
|
||||
|
||||
if (!$root[rootConfigKey].initialized) {
|
||||
ensuredPush($options, '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 ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) {
|
||||
$root[rootConfigKey].appId = options.ssrAppId
|
||||
}
|
||||
})
|
||||
if (!$root[rootConfigKey].initializedSsr) {
|
||||
$root[rootConfigKey].initializedSsr = true
|
||||
|
||||
ensuredPush($options, 'beforeMount', function () {
|
||||
const $root = this
|
||||
// if this Vue-app was server rendered, set the appId to 'ssr'
|
||||
// only one SSR app per page is supported
|
||||
if ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) {
|
||||
$root[rootConfigKey].appId = options.ssrAppId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// we use the mounted hook here as on page load
|
||||
ensuredPush($options, 'mounted', function () {
|
||||
@@ -155,6 +172,7 @@ export default function createMixin (Vue, options) {
|
||||
if (!this.$parent || !hasMetaInfo(this)) {
|
||||
return
|
||||
}
|
||||
delete this._hasMetaInfo
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (!options.waitOnDestroyed || !this.$el || !this.$el.offsetParent) {
|
||||
|
||||
@@ -11,6 +11,19 @@
|
||||
// which means the polyfills are removed for other build formats
|
||||
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) {
|
||||
if (polyfill && !Array.prototype.findIndex) {
|
||||
// idx needs to be a Number, for..in returns string
|
||||
|
||||
+12
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @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 { hasGlobalWindowFn } from '../../src/utils/window'
|
||||
|
||||
@@ -29,6 +29,17 @@ describe('shared', () => {
|
||||
})
|
||||
|
||||
/* 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', () => {
|
||||
const _findIndex = Array.prototype.findIndex
|
||||
Array.prototype.findIndex = false
|
||||
|
||||
Reference in New Issue
Block a user