mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-11 23:42:24 +03:00
switch to beforemount hook & improve test timing logic
This commit is contained in:
@@ -309,7 +309,7 @@ In any of your components, define a `metaInfo` property:
|
||||
|
||||
# Performance
|
||||
|
||||
On the client, `vue-meta` batches DOM updates using [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). It needs to do this because it registers a Vue mixin that subscribes to the [`mounted`](https://vuejs.org/api/#mounted) lifecycle hook on all components in order to be notified that renders have occurred and data is ready. If `vue-meta` did not batch updates, the DOM meta info would be re-calculated and re-updated for every component on the page in quick-succession.
|
||||
On the client, `vue-meta` batches DOM updates using [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). It needs to do this because it registers a Vue mixin that subscribes to the [`beforeMount`](https://vuejs.org/api/#beforeMount) lifecycle hook on all components in order to be notified that renders have occurred and data is ready. If `vue-meta` did not batch updates, the DOM meta info would be re-calculated and re-updated for every component on the page in quick-succession.
|
||||
|
||||
Thanks to batch updating, the update will only occurr once - even if the correct meta info has already been compiled by the server. If you don't want this behaviour, see below.
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"cross-env": "^3.1.3",
|
||||
"css-loader": "^0.25.0",
|
||||
"doctoc": "^1.2.0",
|
||||
"es6-promise": "^4.0.5",
|
||||
"express": "^4.14.0",
|
||||
"express-urlrewrite": "^1.2.0",
|
||||
"file-loader": "^0.9.0",
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ export default function VueMeta (Vue) {
|
||||
|
||||
// watch for client side component updates
|
||||
Vue.mixin({
|
||||
mounted () {
|
||||
beforeMount () {
|
||||
// batch potential DOM updates to prevent extraneous re-rendering
|
||||
window.cancelAnimationFrame(requestId)
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function VueMeta (Vue) {
|
||||
requestId = null
|
||||
|
||||
// update the meta info
|
||||
updateClientMetaInfo(getMetaInfo(this.$root))
|
||||
updateClientMetaInfo(getMetaInfo(this.$root), this.$root)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -11,7 +11,7 @@ if (typeof window !== 'undefined' && window !== null) {
|
||||
*
|
||||
* @param {Object} newInfo - the meta info to update to
|
||||
*/
|
||||
export default function updateClientMetaInfo (newInfo) {
|
||||
export default function updateClientMetaInfo (newInfo, $root) {
|
||||
// if this is not a server render, then update
|
||||
if (htmlTag.getAttribute(SERVER_RENDERED_ATTRIBUTE) === null) {
|
||||
if (newInfo.title) {
|
||||
@@ -24,4 +24,9 @@ export default function updateClientMetaInfo (newInfo) {
|
||||
} else {
|
||||
htmlTag.removeAttribute(SERVER_RENDERED_ATTRIBUTE)
|
||||
}
|
||||
|
||||
// HACK: since we're performing DOM side effects, we can't rely on
|
||||
// Vue.nextTick in our tests. This event helps keep the test suite
|
||||
// free of setTimeout clutter
|
||||
$root.$emit('vue-meta-update')
|
||||
}
|
||||
|
||||
+21
-17
@@ -1,25 +1,29 @@
|
||||
import Vue from 'vue'
|
||||
import Meta from 'vue-meta'
|
||||
|
||||
import { Promise } from 'es6-promise'
|
||||
|
||||
Vue.use(Meta)
|
||||
|
||||
before(() => {
|
||||
new Vue({
|
||||
template: `
|
||||
<div id="app">
|
||||
</div>
|
||||
`,
|
||||
metaInfo: {
|
||||
title: 'Foo'
|
||||
}
|
||||
}).$mount()
|
||||
})
|
||||
|
||||
describe('basic', () => {
|
||||
it('sets the document title', (done) => {
|
||||
setTimeout(() => {
|
||||
expect(document.title).to.equal('Foo')
|
||||
done()
|
||||
}, 100)
|
||||
const container = document.createElement('div')
|
||||
let vm
|
||||
|
||||
function setMetaInfo (metaInfo) {
|
||||
return new Promise((resolve) => {
|
||||
vm = new Vue({ el: container, metaInfo })
|
||||
vm.$on('vue-meta-update', resolve)
|
||||
})
|
||||
}
|
||||
|
||||
afterEach(() => vm.$destroy())
|
||||
|
||||
it('sets a title', () => setMetaInfo({ title: 'Foo' })
|
||||
.then(() => expect(document.title).to.equal('Foo')))
|
||||
|
||||
it('sets a title with a template', () => setMetaInfo({
|
||||
title: 'Foo',
|
||||
titleTemplate: '%s Bar'
|
||||
})
|
||||
.then(() => expect(document.title).to.equal('Foo Bar')))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user