2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-22 13:10:34 +03:00

circumvent need to call refresh() after async actions

This commit is contained in:
Declan de Wet
2016-11-10 22:24:38 +02:00
parent c20206d859
commit 1c9f6d08f3
5 changed files with 54 additions and 42 deletions
+17
View File
@@ -0,0 +1,17 @@
/**
* Performs a batched update. Uses requestAnimationFrame to prevent
* calling a function too many times in quick succession.
* You need to pass it an ID (which can initially be `null`),
* but be sure to overwrite that ID with the return value of batchUpdate.
*
* @param {(null|Number)} id - the ID of this update
* @param {Function} callback - the update to perform
* @return {Number} id - a new ID
*/
export default function batchUpdate (id, callback) {
window.cancelAnimationFrame(id)
return window.requestAnimationFrame(() => {
id = null
callback()
})
}
+21 -7
View File
@@ -1,5 +1,6 @@
import assign from 'object-assign'
import $meta from './$meta'
import batchUpdate from '../client/batchUpdate'
import {
VUE_META_KEY_NAME,
@@ -33,18 +34,31 @@ export default function VueMeta (Vue, options = {}) {
Vue.prototype.$meta = $meta(options)
// store an id to keep track of DOM updates
let requestId = null
let batchID = null
// watch for client side component updates
Vue.mixin({
beforeCreate () {
// coerce function-style metaInfo to a computed prop so we can observe
// it on creation
if (typeof this.$options[options.keyName] === 'function') {
this.$options.computed.$metaInfo = this.$options[options.keyName]
}
},
created () {
// if computed $metaInfo exists, watch it for updates & trigger a refresh
// when it changes (i.e. automatically handle async actions that affect metaInfo)
// credit for this suggestion goes to [Sébastien Chopin](https://github.com/Atinux)
if (this.$metaInfo) {
this.$watch('$metaInfo', () => {
// batch potential DOM updates to prevent extraneous re-rendering
batchID = batchUpdate(batchID, () => this.$meta().refresh())
})
}
},
beforeMount () {
// batch potential DOM updates to prevent extraneous re-rendering
window.cancelAnimationFrame(requestId)
requestId = window.requestAnimationFrame(() => {
requestId = null
this.$meta().refresh()
})
batchID = batchUpdate(batchID, () => this.$meta().refresh())
}
})
}