mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-24 04:20:34 +03:00
@@ -1,5 +1,4 @@
|
|||||||
import deepmerge from 'deepmerge'
|
import deepmerge from 'deepmerge'
|
||||||
import isArray from './isArray'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the `opts.option` $option value of the given `opts.component`.
|
* Returns the `opts.option` $option value of the given `opts.component`.
|
||||||
@@ -25,10 +24,16 @@ export default function getComponentOption (opts, result = {}) {
|
|||||||
if (typeof $options[option] !== 'undefined' && $options[option] !== null) {
|
if (typeof $options[option] !== 'undefined' && $options[option] !== null) {
|
||||||
let data = $options[option]
|
let data = $options[option]
|
||||||
|
|
||||||
if (isArray(data)) {
|
// if option is a function, replace it with it's result
|
||||||
result = data.reduce((result, dataItem) => mergeDataInResult(dataItem, result, component, arrayMerge), result)
|
if (typeof data === 'function') {
|
||||||
|
data = data.call(component)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof data === 'object') {
|
||||||
|
// merge with existing options
|
||||||
|
result = deepmerge(result, data, { arrayMerge })
|
||||||
} else {
|
} else {
|
||||||
result = mergeDataInResult(data, result, component, arrayMerge)
|
result = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,16 +67,3 @@ export default function getComponentOption (opts, result = {}) {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeDataInResult (data, result, component, arrayMerge) {
|
|
||||||
// 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
|
|
||||||
return deepmerge(result, data, { arrayMerge })
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -35,9 +35,6 @@ export default function VueMeta (Vue, options = {}) {
|
|||||||
// bind the $meta method to this component instance
|
// bind the $meta method to this component instance
|
||||||
Vue.prototype.$meta = $meta(options)
|
Vue.prototype.$meta = $meta(options)
|
||||||
|
|
||||||
// define optionMergeStrategies for the keyName
|
|
||||||
Vue.config.optionMergeStrategies[options.keyName] = Vue.config.optionMergeStrategies.created
|
|
||||||
|
|
||||||
// store an id to keep track of DOM updates
|
// store an id to keep track of DOM updates
|
||||||
let batchID = null
|
let batchID = null
|
||||||
|
|
||||||
|
|||||||
@@ -43,23 +43,19 @@ describe('getComponentOption', () => {
|
|||||||
expect(mergedOption).to.eql({ bar: 'baz', fizz: 'buzz' })
|
expect(mergedOption).to.eql({ bar: 'baz', fizz: 'buzz' })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows for a custom array merge strategy in object literal', () => {
|
it('allows for a custom array merge strategy', () => {
|
||||||
Vue.component('array-child', {
|
Vue.component('array-child', {
|
||||||
template: '<div></div>',
|
template: '<div></div>',
|
||||||
foo: {
|
foo: [
|
||||||
flowers: [
|
{ name: 'flower', content: 'rose' }
|
||||||
{ name: 'flower', content: 'rose' }
|
]
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
component = new Vue({
|
component = new Vue({
|
||||||
render: (h) => h('div', null, [h('array-child')]),
|
render: (h) => h('div', null, [h('array-child')]),
|
||||||
foo: {
|
foo: [
|
||||||
flowers: [
|
{ name: 'flower', content: 'tulip' }
|
||||||
{ name: 'flower', content: 'tulip' }
|
],
|
||||||
]
|
|
||||||
},
|
|
||||||
el: container
|
el: container
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -72,64 +68,9 @@ describe('getComponentOption', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mergedOption).to.eql({
|
expect(mergedOption).to.eql([
|
||||||
flowers: [
|
{ name: 'flower', content: 'tulip' },
|
||||||
{ name: 'flower', content: 'tulip' },
|
{ name: 'flower', content: 'rose' }
|
||||||
{ name: 'flower', content: 'rose' }
|
])
|
||||||
]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('merges arrays of objects literal options', () => {
|
|
||||||
component = new Vue({ someOption: [{ foo: 'hello' }, { bar: 'there' }] })
|
|
||||||
|
|
||||||
const mergedOption = getComponentOption({ component, option: 'someOption' })
|
|
||||||
expect(mergedOption).to.eql({ foo: 'hello', bar: 'there' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('merges arrays of mixed object literals and functions', () => {
|
|
||||||
component = new Vue({
|
|
||||||
cake: 'good',
|
|
||||||
desserts: [
|
|
||||||
{ yogurt: 'meh' },
|
|
||||||
function someFunction () {
|
|
||||||
return { cake: this.$options.cake }
|
|
||||||
},
|
|
||||||
function someOtherFunction () {
|
|
||||||
return { pineapple: 'not bad' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const mergedOption = getComponentOption({ component, option: 'desserts' })
|
|
||||||
expect(mergedOption).to.eql({ yogurt: 'meh', cake: 'good', pineapple: 'not bad' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('uses custom array merge strategy when merging arrays in arrays of options', () => {
|
|
||||||
component = new Vue({
|
|
||||||
template: '<div></div>',
|
|
||||||
foo: [
|
|
||||||
{ cars: [{ brand: 'renault', color: 'red' }] },
|
|
||||||
function someFunction () {
|
|
||||||
return { cars: [{ brand: 'peugeot', color: 'blue' }] }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const mergedOption = getComponentOption({
|
|
||||||
component,
|
|
||||||
option: 'foo',
|
|
||||||
deep: true,
|
|
||||||
arrayMerge (target, source) {
|
|
||||||
return target.concat(source)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(mergedOption).to.eql({
|
|
||||||
cars: [
|
|
||||||
{ brand: 'renault', color: 'red' },
|
|
||||||
{ brand: 'peugeot', color: 'blue' }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ const defaultOptions = {
|
|||||||
|
|
||||||
const getMetaInfo = _getMetaInfo(defaultOptions)
|
const getMetaInfo = _getMetaInfo(defaultOptions)
|
||||||
|
|
||||||
// define optionMergeStrategies for the keyName
|
|
||||||
Vue.config.optionMergeStrategies[VUE_META_KEY_NAME] = Vue.config.optionMergeStrategies.created
|
|
||||||
|
|
||||||
describe('getMetaInfo', () => {
|
describe('getMetaInfo', () => {
|
||||||
// const container = document.createElement('div')
|
// const container = document.createElement('div')
|
||||||
let component
|
let component
|
||||||
@@ -533,92 +530,4 @@ describe('getMetaInfo', () => {
|
|||||||
__dangerouslyDisableSanitizersByTagID: {}
|
__dangerouslyDisableSanitizersByTagID: {}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('properly merges mixins options', () => {
|
|
||||||
const mixin1 = {
|
|
||||||
metaInfo: function () {
|
|
||||||
return {
|
|
||||||
title: 'This title will be overridden',
|
|
||||||
meta: [
|
|
||||||
{
|
|
||||||
vmid: 'og:title',
|
|
||||||
property: 'og:title',
|
|
||||||
content: 'This title will be overridden'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vmid: 'og:fromMixin1',
|
|
||||||
property: 'og:fromMixin1',
|
|
||||||
content: 'This is from mixin1'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const mixin2 = {
|
|
||||||
metaInfo: {
|
|
||||||
meta: [
|
|
||||||
{
|
|
||||||
vmid: 'og:fromMixin2',
|
|
||||||
property: 'og:fromMixin2',
|
|
||||||
content: 'This is from mixin2'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const component = new Vue({
|
|
||||||
mixins: [mixin1, mixin2],
|
|
||||||
metaInfo: {
|
|
||||||
title: 'New Title',
|
|
||||||
meta: [
|
|
||||||
{
|
|
||||||
vmid: 'og:title',
|
|
||||||
property: 'og:title',
|
|
||||||
content: 'New Title! - My page'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vmid: 'og:description',
|
|
||||||
property: 'og:description',
|
|
||||||
content: 'Some Description'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
expect(getMetaInfo(component)).to.eql({
|
|
||||||
title: 'New Title',
|
|
||||||
titleChunk: 'New Title',
|
|
||||||
titleTemplate: '%s',
|
|
||||||
htmlAttrs: {},
|
|
||||||
headAttrs: {},
|
|
||||||
bodyAttrs: {},
|
|
||||||
meta: [
|
|
||||||
{
|
|
||||||
vmid: 'og:fromMixin1',
|
|
||||||
property: 'og:fromMixin1',
|
|
||||||
content: 'This is from mixin1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vmid: 'og:fromMixin2',
|
|
||||||
property: 'og:fromMixin2',
|
|
||||||
content: 'This is from mixin2'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vmid: 'og:title',
|
|
||||||
property: 'og:title',
|
|
||||||
content: 'New Title! - My page'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vmid: 'og:description',
|
|
||||||
property: 'og:description',
|
|
||||||
content: 'Some Description'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
base: [],
|
|
||||||
link: [],
|
|
||||||
style: [],
|
|
||||||
script: [],
|
|
||||||
noscript: [],
|
|
||||||
__dangerouslyDisableSanitizers: [],
|
|
||||||
__dangerouslyDisableSanitizersByTagID: {}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -30,9 +30,4 @@ describe('plugin', () => {
|
|||||||
const vm = new Vue(Component).$mount()
|
const vm = new Vue(Component).$mount()
|
||||||
expect(vm._hasMetaInfo).to.equal(true)
|
expect(vm._hasMetaInfo).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('setup optionMergeStrategies for the keyName', () => {
|
|
||||||
const strats = Vue.config.optionMergeStrategies
|
|
||||||
expect(strats[VUE_META_KEY_NAME]).to.equal(strats.created)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user