Skip to content

Commit 9c80dab

Browse files
committed
fix: use single object prop on
feat: provide hasMetaInfo export for other libraries to check if metaInfo has been defined chore: deprecate _hasMetaInfo
1 parent 5935cf3 commit 9c80dab

File tree

9 files changed

+83
-20
lines changed

9 files changed

+83
-20
lines changed

src/browser.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import createMixin from './shared/mixin'
33
import setOptions from './shared/options'
44
import { isUndefined } from './shared/typeof'
55
import $meta from './client/$meta'
6+
export { hasMetaInfo } from './shared/hasMetaInfo'
67

78
/**
89
* Plugin install function.
@@ -13,7 +14,7 @@ function VueMeta(Vue, options = {}) {
1314

1415
Vue.prototype.$meta = $meta(options)
1516

16-
Vue.mixin(createMixin(options))
17+
Vue.mixin(createMixin(Vue, options))
1718
}
1819

1920
VueMeta.version = version

src/client/triggerUpdate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import batchUpdate from './batchUpdate'
44
let batchId = null
55

66
export default function triggerUpdate(vm, hookName) {
7-
if (vm.$root._vueMetaInitialized && !vm.$root._vueMetaPaused) {
7+
if (vm.$root._vueMeta.initialized && !vm.$root._vueMeta.paused) {
88
// batch potential DOM updates to prevent extraneous re-rendering
99
batchId = batchUpdate(batchId, () => {
1010
vm.$meta().refresh()

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { version } from '../package.json'
22
import createMixin from './shared/mixin'
33
import setOptions from './shared/options'
44
import $meta from './server/$meta'
5+
export { hasMetaInfo } from './shared/hasMetaInfo'
56

67
/**
78
* Plugin install function.
@@ -12,7 +13,7 @@ function VueMeta(Vue, options = {}) {
1213

1314
Vue.prototype.$meta = $meta(options)
1415

15-
Vue.mixin(createMixin(options))
16+
Vue.mixin(createMixin(Vue, options))
1617
}
1718

1819
VueMeta.version = version

src/shared/hasMetaInfo.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function hasMetaInfo(vm = this) {
2+
return vm && !!vm._vueMeta
3+
}

src/shared/mixin.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,35 @@ import triggerUpdate from '../client/triggerUpdate'
22
import { isUndefined, isFunction } from './typeof'
33
import { ensuredPush } from './ensure'
44

5-
export default function createMixin(options) {
5+
export default function createMixin(Vue, options) {
66
// for which Vue lifecycle hooks should the metaInfo be refreshed
77
const updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']
88

99
// watch for client side component updates
1010
return {
1111
beforeCreate() {
12+
Object.defineProperty(this, '_hasMetaInfo', {
13+
get() {
14+
// Show deprecation warning once when devtools enabled
15+
if (Vue.config.devtools && !this.$root._vueMeta.hasMetaInfoDeprecationWarningShown) {
16+
console.warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please import hasMetaInfo and use hasMetaInfo(vm) instead') // eslint-disable-line no-console
17+
this.$root._vueMeta.hasMetaInfoDeprecationWarningShown = true
18+
}
19+
return !!this._vueMeta
20+
}
21+
})
22+
1223
// Add a marker to know if it uses metaInfo
1324
// _vnode is used to know that it's attached to a real component
1425
// useful if we use some mixin to add some meta tags (like nuxt-i18n)
1526
if (!isUndefined(this.$options[options.keyName]) && this.$options[options.keyName] !== null) {
16-
this._hasMetaInfo = true
27+
if (!this.$root._vueMeta) {
28+
this.$root._vueMeta = {}
29+
}
30+
31+
if (!this._vueMeta) {
32+
this._vueMeta = true
33+
}
1734

1835
// coerce function-style metaInfo to a computed prop so we can observe
1936
// it on creation
@@ -39,18 +56,18 @@ export default function createMixin(options) {
3956
// to triggerUpdate until this initial refresh is finished
4057
// this is to make sure that when a page is opened in an inactive tab which
4158
// has throttled rAF/timers we still immeditately set the page title
42-
if (isUndefined(this.$root._vueMetaInitialized)) {
43-
this.$root._vueMetaInitialized = this.$isServer
59+
if (isUndefined(this.$root._vueMeta.initialized)) {
60+
this.$root._vueMeta.initialized = this.$isServer
4461

45-
if (!this.$root._vueMetaInitialized) {
62+
if (!this.$root._vueMeta.initialized) {
4663
const $rootMeta = this.$root.$meta()
4764

4865
ensuredPush(this.$options, 'mounted', () => {
49-
if (!this.$root._vueMetaInitialized) {
66+
if (!this.$root._vueMeta.initialized) {
5067
// refresh meta in nextTick so all child components have loaded
5168
this.$nextTick(function () {
5269
$rootMeta.refresh()
53-
this.$root._vueMetaInitialized = true
70+
this.$root._vueMeta.initialized = true
5471
})
5572
}
5673
})

src/shared/pausing.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
export function pause(refresh = true) {
2-
this.$root._vueMetaPaused = true
2+
this.$root._vueMeta.paused = true
33

44
return () => resume(refresh)
55
}
66

77
export function resume(refresh = true) {
8-
this.$root._vueMetaPaused = false
8+
this.$root._vueMeta.paused = false
99

1010
if (refresh) {
1111
return this.$root.$meta().refresh()

test/plugin-browser.test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ describe('plugin', () => {
7272
})
7373

7474
// no batchUpdate on initialization
75-
expect(wrapper.vm.$root._vueMetaInitialized).toBe(false)
76-
expect(wrapper.vm.$root._vueMetaPaused).toBeFalsy()
75+
expect(wrapper.vm.$root._vueMeta.initialized).toBe(false)
76+
expect(wrapper.vm.$root._vueMeta.paused).toBeFalsy()
7777
expect(triggerUpdateSpy).toHaveBeenCalledTimes(1)
7878
expect(batchUpdateSpy).not.toHaveBeenCalled()
7979
jest.clearAllMocks()
@@ -83,8 +83,8 @@ describe('plugin', () => {
8383
wrapper.setProps({ title })
8484

8585
// batchUpdate on normal update
86-
expect(wrapper.vm.$root._vueMetaInitialized).toBe(true)
87-
expect(wrapper.vm.$root._vueMetaPaused).toBeFalsy()
86+
expect(wrapper.vm.$root._vueMeta.initialized).toBe(true)
87+
expect(wrapper.vm.$root._vueMeta.paused).toBeFalsy()
8888
expect(triggerUpdateSpy).toHaveBeenCalledTimes(1)
8989
expect(batchUpdateSpy).toHaveBeenCalledTimes(1)
9090
jest.clearAllMocks()
@@ -94,8 +94,8 @@ describe('plugin', () => {
9494
wrapper.setProps({ title })
9595

9696
// no batchUpdate when paused
97-
expect(wrapper.vm.$root._vueMetaInitialized).toBe(true)
98-
expect(wrapper.vm.$root._vueMetaPaused).toBe(true)
97+
expect(wrapper.vm.$root._vueMeta.initialized).toBe(true)
98+
expect(wrapper.vm.$root._vueMeta.paused).toBe(true)
9999
expect(triggerUpdateSpy).toHaveBeenCalledTimes(1)
100100
expect(batchUpdateSpy).not.toHaveBeenCalled()
101101
jest.clearAllMocks()

test/plugin-server.test.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mount, defaultOptions, VueMetaServerPlugin, loadVueMetaPlugin } from './utils'
1+
import { mount, defaultOptions, hasMetaInfo, VueMetaServerPlugin, loadVueMetaPlugin } from './utils'
22

33
jest.mock('../package.json', () => ({
44
version: 'test-version'
@@ -7,6 +7,7 @@ jest.mock('../package.json', () => ({
77
describe('plugin', () => {
88
let Vue
99

10+
beforeEach(() => jest.clearAllMocks())
1011
beforeAll(() => (Vue = loadVueMetaPlugin()))
1112

1213
test('is loaded', () => {
@@ -29,4 +30,43 @@ describe('plugin', () => {
2930
test('plugin sets package version', () => {
3031
expect(VueMetaServerPlugin.version).toBe('test-version')
3132
})
33+
34+
test('prints deprecation warning once when using _hasMetaInfo', () => {
35+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
36+
37+
const Component = Vue.component('test-component', {
38+
template: '<div>Test</div>',
39+
[defaultOptions.keyName]: {
40+
title: 'Hello World'
41+
}
42+
})
43+
44+
Vue.config.devtools = true
45+
const { vm } = mount(Component, { localVue: Vue })
46+
47+
expect(vm._hasMetaInfo).toBe(true)
48+
expect(warn).toHaveBeenCalledTimes(1)
49+
50+
expect(vm._hasMetaInfo).toBe(true)
51+
expect(warn).toHaveBeenCalledTimes(1)
52+
warn.mockRestore()
53+
})
54+
55+
test('can use hasMetaInfo export', () => {
56+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
57+
58+
const Component = Vue.component('test-component', {
59+
template: '<div>Test</div>',
60+
[defaultOptions.keyName]: {
61+
title: 'Hello World'
62+
}
63+
})
64+
65+
const { vm } = mount(Component, { localVue: Vue })
66+
67+
expect(hasMetaInfo(vm)).toBe(true)
68+
expect(warn).not.toHaveBeenCalled()
69+
70+
warn.mockRestore()
71+
})
3272
})

test/utils/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { mount, createLocalVue } from '@vue/test-utils'
22
import { renderToString } from '@vue/server-test-utils'
33
import VueMetaBrowserPlugin from '../../src/browser'
4-
import VueMetaServerPlugin from '../../src'
4+
import VueMetaServerPlugin, { hasMetaInfo } from '../../src'
55

66
import {
77
keyName,
@@ -15,6 +15,7 @@ import {
1515
export {
1616
mount,
1717
renderToString,
18+
hasMetaInfo,
1819
VueMetaBrowserPlugin,
1920
VueMetaServerPlugin
2021
}

0 commit comments

Comments
 (0)