2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-23 20:10:33 +03:00

plan for more intuitive api

This commit is contained in:
Declan de Wet
2016-10-30 08:08:31 +02:00
parent 4fa1c133f3
commit d514cdc1bc
2 changed files with 51 additions and 17 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ indent_size = 2
end_of_line = lf end_of_line = lf
charset = utf-8 charset = utf-8
trim_trailing_whitespace = false trim_trailing_whitespace = false
insert_final_newline = false insert_final_newline = true
[*.md] [*.md]
trim_trailing_whitespace = false trim_trailing_whitespace = false
+49 -15
View File
@@ -4,6 +4,9 @@
// initialize vue-meta // initialize vue-meta
var VueMeta = {} var VueMeta = {}
// initialize manager
var _manager = {}
/** /**
* Registers the plugin with Vue.js * Registers the plugin with Vue.js
* Pass it like so: Vue.use(VueMeta) * Pass it like so: Vue.use(VueMeta)
@@ -15,29 +18,47 @@
// set installation inspection flag // set installation inspection flag
VueMeta.install.installed = true VueMeta.install.installed = true
// listen for when components mount - when they do, // listen for when components mount - when they do,
// update the meta info & the DOM // update the meta info & the DOM
Vue.mixin({ Vue.mixin({
mounted () { mounted: function mounted () {
this.$root.$updateMeta() this.$root.$vueMeta.updateMetaInfo()
} }
}) })
/** // guard against `$vueMeta` being redefined on new server requests
* Updates meta info and renders it to the DOM if (!Vue.prototype.hasOwnProperty('$vueMeta')) {
*/ // define API methods on the `$vueMeta` instance property
Vue.prototype.$updateMeta = function $updateMeta () { Object.defineProperty(Vue.prototype, '$vueMeta', {
var newMeta = this.$meta() enumerable: true,
document.title = newMeta.title /**
* Meta info manager API factory
* @return {Object} - the API for this plugin
*/
get: function get () {
_manager.getMetaInfo = _manager.getMetaInfo || Vue.util.bind(getMetaInfo, this)
_manager.updateMetaInfo = _manager.updateMetaInfo || updateMetaInfo
return _manager
}
})
} }
/** /**
* Does the grunt work of exposing component meta options * Updates meta info and renders it to the DOM
* to the server-rendered context */
function updateMetaInfo () {
var newMeta = this.getMetaInfo()
if (newMeta.title) {
updateTitle(newMeta.title)
}
}
/**
* Fetches corresponding meta info for the current component state
* @return {Object} - all the meta info for currently matched components * @return {Object} - all the meta info for currently matched components
*/ */
Vue.prototype.$meta = function $meta () { function getMetaInfo () {
return getMetaInfoDefinition(Vue, this) return getMetaInfoDefinition(Vue, this)
} }
} }
@@ -46,11 +67,11 @@
* Recursively traverses each component, checking for a `metaInfo` * Recursively traverses each component, checking for a `metaInfo`
* option. It then merges all these options into one object, giving * option. It then merges all these options into one object, giving
* higher priority to deeply nested components. * higher priority to deeply nested components.
* *
* NOTE: This function uses Vue.prototype.$children, the results of which * NOTE: This function uses Vue.prototype.$children, the results of which
* are not gauranted to be in order. For this reason, try to avoid * are not gauranted to be in order. For this reason, try to avoid
* using the same `metaInfo` property in sibling components. * using the same `metaInfo` property in sibling components.
* *
* @param {Function} Vue - the Vue constructor * @param {Function} Vue - the Vue constructor
* @param {Object} $instance - the current instance * @param {Object} $instance - the current instance
* @param {Object} [metaInfo={}] - the merged options * @param {Object} [metaInfo={}] - the merged options
@@ -59,10 +80,12 @@
function getMetaInfoDefinition (Vue, $instance, metaInfo) { function getMetaInfoDefinition (Vue, $instance, metaInfo) {
// set default for first run // set default for first run
metaInfo = metaInfo || {} metaInfo = metaInfo || {}
// if current instance has a metaInfo option... // if current instance has a metaInfo option...
if ($instance.$options.metaInfo) { if ($instance.$options.metaInfo) {
var componentMetaInfo = $instance.$options.metaInfo var componentMetaInfo = $instance.$options.metaInfo
var key var key
// ...convert all function type keys to raw data // ...convert all function type keys to raw data
// (this allows meta info to be inferred from props & data)... // (this allows meta info to be inferred from props & data)...
for (key in componentMetaInfo) { for (key in componentMetaInfo) {
@@ -73,9 +96,11 @@
} }
} }
} }
// ...then merge the data into metaInfo // ...then merge the data into metaInfo
metaInfo = Vue.util.mergeOptions(metaInfo, componentMetaInfo) metaInfo = Vue.util.mergeOptions(metaInfo, componentMetaInfo)
} }
// check if any children also have a metaInfo option, if so, merge // check if any children also have a metaInfo option, if so, merge
// them into existing data // them into existing data
var len = $instance.$children.length var len = $instance.$children.length
@@ -85,9 +110,18 @@
metaInfo = getMetaInfoDefinition(Vue, $instance.$children[i], metaInfo) metaInfo = getMetaInfoDefinition(Vue, $instance.$children[i], metaInfo)
} }
} }
return metaInfo return metaInfo
} }
/**
* updates the document title
* @param {String} title - the new title of the document
*/
function updateTitle (title) {
document.title = title || document.title
}
// automatic installation when global context // automatic installation when global context
if (typeof Vue !== 'undefined') { if (typeof Vue !== 'undefined') {
Vue.use(VueMeta) Vue.use(VueMeta)