2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-09 18:32:24 +03:00

More reliable strategy for getting deepmost component + addition of refresh() method + example & documentation on asynchronous updates

This commit is contained in:
Declan de Wet
2016-11-09 07:26:38 +02:00
parent fa290273df
commit 076832cbd6
18 changed files with 268 additions and 45 deletions
+18
View File
@@ -0,0 +1,18 @@
import getMetaInfo from '../shared/getMetaInfo'
import updateClientMetaInfo from './updateClientMetaInfo'
/**
* When called, will update the current meta info with new meta info.
* Useful when updating meta info as the result of an asynchronous
* action that resolves after the initial render takes place.
*
* Credit to [Sébastien Chopin](https://github.com/Atinux) for the suggestion
* to implement this method.
*
* @return {Object} - new meta info
*/
export default function refresh () {
const info = getMetaInfo(this.$root)
updateClientMetaInfo(info)
return info
}
+6 -2
View File
@@ -1,4 +1,5 @@
import inject from './inject'
import inject from '../server/inject'
import refresh from '../client/refresh'
/**
* Returns an injector for server-side rendering.
@@ -7,5 +8,8 @@ import inject from './inject'
*/
export default function $meta () {
// bind inject method to this component
return { inject: inject.bind(this) }
return {
inject: inject.bind(this),
refresh: refresh.bind(this)
}
}
+7 -4
View File
@@ -12,9 +12,11 @@ import deepmerge from 'deepmerge'
* @param {Boolean} opts.deep - look for data in child components as well?
* @param {Function} opts.arrayMerge - how should arrays be merged?
* @param {Object} [result={}] - result so far
* @return {Object} - final aggregated result
* @return {Object} result - final aggregated result
* @return {Object} result.mergedOption - the actual merged options
* @return {Object} result.deepestComponentWithMetaInfo - the deepest component in the heirarchy that has a `metaInfo` instance property
*/
export default function getComponentOption (opts, result = {}) {
export default function getComponentOption (opts, result = { mergedOption: {} }) {
const { component, option, deep, arrayMerge } = opts
const { $options } = component
@@ -24,12 +26,13 @@ export default function getComponentOption (opts, result = {}) {
if (typeof data === 'object') {
// merge with existing options
result = deepmerge(result, data, {
result.mergedOption = deepmerge(result.mergedOption, data, {
clone: true,
arrayMerge
})
result.deepestComponentWithMetaInfo = component
} else {
result = data
result.mergedOption = data
}
}
+2 -4
View File
@@ -1,6 +1,5 @@
import deepmerge from 'deepmerge'
import getComponentOption from './getComponentOption'
import mergeComponentData from './mergeComponentData'
/**
* Returns the correct meta info for the given component
@@ -26,7 +25,7 @@ export default function getMetaInfo (component) {
}
// collect & aggregate all metaInfo $options
const info = getComponentOption({
const { mergedOption: info, deepestComponentWithMetaInfo } = getComponentOption({
component,
option: 'metaInfo',
deep: true,
@@ -73,13 +72,12 @@ export default function getMetaInfo (component) {
}
const metaInfo = deepmerge(defaultInfo, info)
const componentData = mergeComponentData(component)
// inject component context into functions & call to normalize data
Object.keys(metaInfo).forEach((key) => {
const val = metaInfo[key]
if (typeof val === 'function') {
metaInfo[key] = val.call(componentData)
metaInfo[key] = val.call(deepestComponentWithMetaInfo)
}
})
-18
View File
@@ -1,18 +0,0 @@
import assign from 'object-assign'
/**
* Recursively shallow-merges component object with it's children component objects.
* This function is responsible for obtaining the `this` context of metaInfo props when
* declared in function form.
*
* @param {Object} component - the component object
* @return {Object} - the merged data
*/
export default function mergeComponentData (component) {
if (component.$children.length) {
return component.$children.reduce((data, child) => {
return assign({}, data, mergeComponentData(child))
}, component)
}
return component
}
+2 -7
View File
@@ -1,6 +1,4 @@
import getMetaInfo from './getMetaInfo'
import $meta from '../server/$meta'
import updateClientMetaInfo from '../client/updateClientMetaInfo'
import $meta from './$meta'
// automatic install
if (typeof Vue !== 'undefined') {
@@ -26,10 +24,7 @@ export default function VueMeta (Vue) {
requestId = window.requestAnimationFrame(() => {
requestId = null
const info = getMetaInfo(this.$root)
// update the meta info
updateClientMetaInfo(info)
this.$meta().refresh()
})
}
})