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:
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user