diff --git a/README.md b/README.md index 3961e49..4601e96 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,7 @@ - [Performance](#performance) - [How to prevent the update on the initial page render](#how-to-prevent-the-update-on-the-initial-page-render) - [FAQ](#faq) - - [How do I use component data in `metaInfo`?](#how-do-i-use-component-data-in-metainfo) - - [How do I use component props in `metaInfo`?](#how-do-i-use-component-props-in-metainfo) + - [How do I use component props and/or component data in `metaInfo`?](#how-do-i-use-component-props-andor-component-data-in-metainfo) - [How do I populate `metaInfo` from the result of an asynchronous action?](#how-do-i-populate-metainfo-from-the-result-of-an-asynchronous-action) - [Examples](#examples) @@ -610,71 +609,56 @@ Add the `data-vue-meta-server-rendered` attribute to the `` tag on the ser Here are some answers to some frequently asked questions. -## How do I use component data in `metaInfo`? -Specify a function instead of an object. It will need to return the same type as its definition. +## How do I use component props and/or component data in `metaInfo`? -**BlogPost.vue:** +Easy. Instead of defining `metaInfo` as an object, define it as a function and access `this` as usual: + +**Post.vue:** ```html ``` -## How do I use component props in `metaInfo`? -The same way you use data - specify a function instead of an object. It will need to return the same type as its definition. - -**BlogPostWrapper.vue** +**PostContainer.vue:** ```html -``` - -**BlogPost.vue** -```html - - - diff --git a/examples/vuex-async/views/Home.vue b/examples/vuex-async/views/Home.vue index b97fdf7..d620373 100644 --- a/examples/vuex-async/views/Home.vue +++ b/examples/vuex-async/views/Home.vue @@ -20,7 +20,10 @@ postsCount: 'publishedPostsCount' }), metaInfo: { - title: 'Home' + title: 'Home', + meta: [ + { vmid: 'description', name: 'description', content: 'The home page' } + ] } } diff --git a/examples/vuex-async/views/Post.vue b/examples/vuex-async/views/Post.vue index c648891..5032983 100644 --- a/examples/vuex-async/views/Post.vue +++ b/examples/vuex-async/views/Post.vue @@ -28,9 +28,12 @@ 'isLoading', 'post' ]), - metaInfo: { - title () { - return this.isLoading ? 'Loading...' : this.post.title + metaInfo () { + return { + title: this.isLoading ? 'Loading...' : this.post.title, + meta: [ + { vmid: 'description', name: 'description', content: this.post.title } + ] } } } diff --git a/examples/vuex/App.vue b/examples/vuex/App.vue index 0ff3c68..5c14077 100644 --- a/examples/vuex/App.vue +++ b/examples/vuex/App.vue @@ -5,3 +5,13 @@

Inspect Element to see the meta info

+ + diff --git a/examples/vuex/views/Home.vue b/examples/vuex/views/Home.vue index b97fdf7..d620373 100644 --- a/examples/vuex/views/Home.vue +++ b/examples/vuex/views/Home.vue @@ -20,7 +20,10 @@ postsCount: 'publishedPostsCount' }), metaInfo: { - title: 'Home' + title: 'Home', + meta: [ + { vmid: 'description', name: 'description', content: 'The home page' } + ] } } diff --git a/examples/vuex/views/Post.vue b/examples/vuex/views/Post.vue index 1a1202c..26d3a3c 100644 --- a/examples/vuex/views/Post.vue +++ b/examples/vuex/views/Post.vue @@ -18,9 +18,12 @@ computed: mapGetters([ 'post' ]), - metaInfo: { - title () { - return this.post.title + metaInfo () { + return { + title: this.post.title, + meta: [ + { vmid: 'description', name: 'description', content: this.post.title } + ] } } } diff --git a/src/shared/getComponentOption.js b/src/shared/getComponentOption.js index 6667252..58e2405 100644 --- a/src/shared/getComponentOption.js +++ b/src/shared/getComponentOption.js @@ -13,26 +13,28 @@ import deepmerge from 'deepmerge' * @param {Function} opts.arrayMerge - how should arrays be merged? * @param {Object} [result={}] - result so far * @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 = { mergedOption: {} }) { +export default function getComponentOption (opts, result = {}) { const { component, option, deep, arrayMerge } = opts const { $options } = component // only collect option data if it exists if (typeof $options[option] !== 'undefined' && $options[option] !== null) { - const data = $options[option] + let data = $options[option] + + // if option is a function, replace it with it's result + if (typeof data === 'function') { + data = data.call(component) + } if (typeof data === 'object') { // merge with existing options - result.mergedOption = deepmerge(result.mergedOption, data, { + result = deepmerge(result, data, { clone: true, arrayMerge }) - result.deepestComponentWithMetaInfo = component } else { - result.mergedOption = data + result = data } } diff --git a/src/shared/getMetaInfo.js b/src/shared/getMetaInfo.js index 90cbd32..3f7fd1a 100644 --- a/src/shared/getMetaInfo.js +++ b/src/shared/getMetaInfo.js @@ -25,7 +25,7 @@ export default function getMetaInfo (component) { } // collect & aggregate all metaInfo $options - const { mergedOption: info, deepestComponentWithMetaInfo } = getComponentOption({ + const info = getComponentOption({ component, option: 'metaInfo', deep: true, @@ -71,15 +71,5 @@ export default function getMetaInfo (component) { info.base = Object.keys(info.base).length ? [info.base] : [] } - const metaInfo = deepmerge(defaultInfo, info) - - // 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(deepestComponentWithMetaInfo) - } - }) - - return metaInfo + return deepmerge(defaultInfo, info) }