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

feat: implement first useApi basics

This commit is contained in:
pimlie
2020-05-18 00:32:02 +02:00
parent 5d0eb1ab60
commit b0edfbe6bd
5 changed files with 172 additions and 84 deletions
+1 -1
View File
@@ -48,7 +48,7 @@ export default {
targets[target].push(vnodes) targets[target].push(vnodes)
continue continue
} }
console.log('TARGETS', targets) // console.log('TARGETS', targets)
return Object.keys(targets).map(target => { return Object.keys(targets).map(target => {
return h(Teleport, { to: target }, targets[target]) return h(Teleport, { to: target }, targets[target])
}) })
+106 -47
View File
@@ -1,68 +1,127 @@
import { markRaw, reactive, onMounted } from 'vue' import { markRaw, reactive, onMounted, customRef, getCurrentInstance } from 'vue'
import { def, hasOwn, isObject, isArray, isPlainObject } from '@vue/shared'
import { defaultMapping } from './config' import { defaultMapping } from './config'
const apps = {} let appId = 0
let appId = 1
export function createMeta ({ config }) { export function createMeta ({ resolver, config }) {
const id = Symbol(`vue-meta-${appId++}`) const id = Symbol(`vueMeta[${appId++}]`)
const Meta = {
id,
return {
install (app) { install (app) {
let watchersAdded = false const $metaInfo = {
id,
resolver,
shadow: markRaw({}),
metainfo: reactive({})
}
app.config.globalProperties.$metaInfo = $metaInfo
app.provide('metainfo', $metaInfo.metainfo)
app.provide('__vueMetaConfig', { app.provide('__vueMetaConfig', {
id,
...defaultMapping, ...defaultMapping,
...config ...config
}) })
app.mixin({
created () {
if (this === this.$root) {
watchersAdded = true
}
if (!this.metaData || watchersAdded) {
return
}
let depth = 0
let parent = this
while (parent) {
parent = parent.$parent
depth++
if (parent === this.$root) {
break
}
}
this.__meta = markRaw({
depth
})
console.log('CREATED', this, this.metaData, depth)
}
})
app.config.globalProperties.$meta = this app.config.globalProperties.$meta = this
} }
} }
apps[id] = Meta
return Meta
} }
export function useMeta (rawMetainfo) { export function useMeta (obj) {
onMounted(vmMounted) const vm = getCurrentInstance()
const metainfo = reactive(rawMetainfo) const { shadow, metainfo } = vm.ctx.$metaInfo
addMetainfoRecursive(obj, vm, shadow, metainfo)
return metainfo return createProxy(obj, createHandler(vm))
} }
function vmMounted () { function createProxy (obj, handler) {
console.log('MOUNTED', this, arguments) return new Proxy(obj, handler)
}
function createHandler (vm, keyPath = []) {
return {
get (target, prop) {
const value = target[prop]
if (isObject(value)) {
if (!value.__vm_proxy) {
const newKeyPath = [...keyPath, prop]
const handler = createHandler(vm, newKeyPath)
value.__vm_proxy = createProxy(value, handler)
}
return value.__vm_proxy
}
return value
},
set (target, prop, value) {
updateMetainfo(keyPath, vm, prop, value)
return true
}
}
}
function addMetainfoRecursive (obj, vm, shadowParent, liveParent) {
for (const key in obj) {
if (isPlainObject(obj[key])) {
if (!shadowParent[key]) {
shadowParent[key] = {}
liveParent[key] = {}
}
addMetainfoRecursive(obj[key], vm, shadowParent[key], liveParent[key])
continue
}
if (!shadowParent[key]) {
shadowParent[key] = []
}
shadowParent[key].push({ vm, value: obj[key] })
setLive(vm, key, shadowParent, liveParent)
}
}
function updateMetainfo (keyPath, vm, key, value) {
let { shadow: shadowParent, metainfo: liveParent } = vm.ctx.$metaInfo
for (const _key of keyPath) {
shadowParent = shadowParent[_key]
liveParent = liveParent[_key]
}
if (isPlainObject(value)) {
if (!shadowParent[key]) {
shadowParent[key] = {}
liveParent[key] = {}
}
// TODO: fix this shit
addMetainfoRecursive(value, vm, shadowParent[key], liveParent[key])
return
}
const idx = shadowParent[key].findIndex(({ vm: _vm }) => _vm === vm)
shadowParent[key][idx].value = value
setLive(vm, key, shadowParent, liveParent)
}
function setLive (vm, key, shadowParent, liveParent) {
let value
if (shadowParent[key].length > 1) {
value = vm.ctx.$metaInfo.resolver(shadowParent[key])
} else {
value = shadowParent[key][0].value
}
if (!hasOwn(liveParent, key) || liveParent[key] !== value) {
liveParent[key] = value
}
} }
+6 -6
View File
@@ -2,7 +2,7 @@ import { h } from 'vue'
import { getConfigKey } from './config' import { getConfigKey } from './config'
export function renderMeta (ctx, key, data, config) { export function renderMeta (ctx, key, data, config) {
console.info('renderMeta', key, data, config) // console.info('renderMeta', key, data, config)
if (config.group) { if (config.group) {
return renderGroup(ctx, key, data, config) return renderGroup(ctx, key, data, config)
@@ -12,7 +12,7 @@ export function renderMeta (ctx, key, data, config) {
} }
export function renderGroup (ctx, key, data, config) { export function renderGroup (ctx, key, data, config) {
console.info('renderGroup', key, data, config) // console.info('renderGroup', key, data, config)
if (Array.isArray(data)) { if (Array.isArray(data)) {
config.contentAttributes = getConfigKey([key, config.tag], 'contentAttributes', config) config.contentAttributes = getConfigKey([key, config.tag], 'contentAttributes', config)
@@ -107,10 +107,10 @@ export function renderTag (ctx, key, data, config = {}, groupConfig = {}) {
? `${groupConfig.tagNamespace}:${tag}` ? `${groupConfig.tagNamespace}:${tag}`
: tag : tag
console.info('FINAL TAG', finalTag) // console.info('FINAL TAG', finalTag)
console.log(' ATTRIBUTES', attributes) // console.log(' ATTRIBUTES', attributes)
console.log(' CONTENT', content) // console.log(' CONTENT', content)
// console.log(data, attributes, config) // // console.log(data, attributes, config)
if (hasChilds) { if (hasChilds) {
for (const child of content) { for (const child of content) {
+7 -7
View File
@@ -20,15 +20,15 @@
}, },
"homepage": "https://github.com/nuxt/vue-meta#readme", "homepage": "https://github.com/nuxt/vue-meta#readme",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.9.0", "@babel/core": "^7.9.6",
"@babel/node": "^7.8.7", "@babel/node": "^7.8.7",
"@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "^7.9.5", "@babel/preset-env": "^7.9.6",
"@vue/compiler-sfc": "^3.0.0-alpha.10", "@vue/compiler-sfc": "^3.0.0-alpha.10",
"@vue/server-renderer": "^3.0.0-alpha.10", "@vue/server-renderer": "^3.0.0-alpha.10",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"babel-plugin-dynamic-import-node": "^2.3.0", "babel-plugin-dynamic-import-node": "^2.3.3",
"consola": "^2.11.3", "consola": "^2.12.1",
"core-js": "3", "core-js": "3",
"cross-env": "^7.0.2", "cross-env": "^7.0.2",
"express": "^4.17.1", "express": "^4.17.1",
@@ -40,9 +40,9 @@
"vue-meta": "^2.3.3", "vue-meta": "^2.3.3",
"vue-router": "next", "vue-router": "next",
"vue-template-compiler": "^2.6.11", "vue-template-compiler": "^2.6.11",
"vuex": "^3.1.3", "vuex": "^3.4.0",
"webpack": "^4.42.1", "webpack": "^4.43.0",
"webpack-dev-server": "^3.10.3", "webpack-dev-server": "^3.11.0",
"webpackbar": "^4.0.0" "webpackbar": "^4.0.0"
} }
} }
+52 -23
View File
@@ -1,10 +1,10 @@
import { createApp, defineComponent, reactive, toRefs, h } from 'vue' import { createApp, defineComponent, reactive, inject, markRaw, toRefs, h, customRef, watch, watchEffect } from 'vue'
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import Metainfo from '../next/Metainfo.vue' import Metainfo from '../next/Metainfo.vue'
import { createMeta, useMeta } from '../next' import { createMeta, useMeta } from '../next'
import About from './about.vue' import About from './about.vue'
let metaUpdated = 'no' const metaUpdated = 'no'
const ChildComponent = defineComponent({ const ChildComponent = defineComponent({
name: 'child-component', name: 'child-component',
@@ -16,19 +16,8 @@ const ChildComponent = defineComponent({
<h3>You're looking at the <strong>{{ page }}</strong> page</h3> <h3>You're looking at the <strong>{{ page }}</strong> page</h3>
<p>Has metaInfo been updated due to navigation? {{ metaUpdated }}</p> <p>Has metaInfo been updated due to navigation? {{ metaUpdated }}</p>
</div>`, </div>`,
metaInfo () {
return {
title: `${this.page} - ${this.date && this.date.toTimeString()}`,
bodyAttrs: {
class: 'child-component'
},
afterNavigation () {
metaUpdated = 'yes'
}
}
},
created () { created () {
//console.log(this) // console.log(this)
}, },
setup () { setup () {
const state = reactive({ const state = reactive({
@@ -36,7 +25,16 @@ const ChildComponent = defineComponent({
metaUpdated metaUpdated
}) })
const metainfo = useMeta({
charset: 'utf16',
description: 'Description 2',
og: {
title: 'Og Title 2'
}
})
return { return {
metainfo,
...toRefs(state) ...toRefs(state)
} }
} }
@@ -53,7 +51,7 @@ function view (page) {
const App = { const App = {
setup () { setup () {
const metainfo = useMeta({ /* const metainfo = useMeta({
base: { href: '/vue-router', target: '_blank' }, base: { href: '/vue-router', target: '_blank' },
charset: 'utf8', charset: 'utf8',
title: 'My Title', title: 'My Title',
@@ -104,7 +102,24 @@ const App = {
} }
}) })
setTimeout(() => (metainfo.title = 'My Updated Title'), 2000) setTimeout(() => (metainfo.title = 'My Updated Title'), 2000) */
const meta = useMeta({
charset: 'utf8',
title: 'Title 1',
og: {
title: 'Og Title 1'
}
})
setTimeout(() => (meta.charset = 'utf17'), 2000)
setTimeout(() => (meta.og = { title: 'Updated Og Title 1' }), 3000) // TODO: fix
const metainfo = inject('metainfo')
watch(metainfo, (newValue, oldValue) => {
console.log('UPDATE', newValue)
})
return { return {
metainfo metainfo
@@ -131,15 +146,21 @@ const App = {
` `
} }
const router = createRouter({ function decisionMaker5000000 (options) {
history: createWebHistory('/vue-router'), let theChosenOne
routes: [
{ name: 'home', path: '/', component: view('home') }, for (const option of options) {
{ name: 'about', path: '/about', component: About } if (!theChosenOne || theChosenOne.vm.id < option.vm.id) {
] theChosenOne = option
}) }
}
console.log(theChosenOne.value)
return theChosenOne.value
}
const meta = createMeta({ const meta = createMeta({
resolver: decisionMaker5000000,
config: { config: {
esi: { esi: {
group: true, group: true,
@@ -153,6 +174,14 @@ const meta = createMeta({
} }
}) })
const router = createRouter({
history: createWebHistory('/vue-router'),
routes: [
{ name: 'home', path: '/', component: view('home') },
{ name: 'about', path: '/about', component: About }
]
})
const app = createApp(App) const app = createApp(App)
app.component('metainfo', Metainfo) app.component('metainfo', Metainfo)
app.use(router) app.use(router)