2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-24 07:40:35 +03:00

feat: first work on vue v3 composition metainfo app

This commit is contained in:
pimlie
2020-05-03 19:59:05 +02:00
parent 41c7561bf9
commit 5d0eb1ab60
21 changed files with 551 additions and 182 deletions
+4
View File
@@ -0,0 +1,4 @@
node_modules
__build__
dist
+2 -2
View File
@@ -10,8 +10,8 @@
<!-- li><a href="basic">Basic</a></li> <!-- li><a href="basic">Basic</a></li>
<li><a href="basic-render">Basic Render</a></li> <li><a href="basic-render">Basic Render</a></li>
<li><a href="keep-alive">Keep alive</a></li> <li><a href="keep-alive">Keep alive</a></li>
<li><a href="multiple-apps">Usage with multiple apps</a></li --> <li><a href="multiple-apps">Usage with multiple apps</a></li>
<li><a href="ssr">SSR</a></li> <li><a href="ssr">SSR</a></li -->
<li><a href="vue-router">Usage with vue-router</a></li> <li><a href="vue-router">Usage with vue-router</a></li>
<!-- li><a href="vuex">Usage with vuex</a></li> <!-- li><a href="vuex">Usage with vuex</a></li>
<li><a href="vuex-async">Usage with vuex + async actions</a></li> <li><a href="vuex-async">Usage with vuex + async actions</a></li>
View File
View File
+18 -18
View File
@@ -1,23 +1,23 @@
window.users.push({ window.users.push({
'id': 1, id: 1,
'name': 'Leanne Graham', name: 'Leanne Graham',
'username': 'Bret', username: 'Bret',
'email': 'Sincere@april.biz', email: 'Sincere@april.biz',
'address': { address: {
'street': 'Kulas Light', street: 'Kulas Light',
'suite': 'Apt. 556', suite: 'Apt. 556',
'city': 'Gwenborough', city: 'Gwenborough',
'zipcode': '92998-3874', zipcode: '92998-3874',
'geo': { geo: {
'lat': '-37.3159', lat: '-37.3159',
'lng': '81.1496' lng: '81.1496'
} }
}, },
'phone': '1-770-736-8031 x56442', phone: '1-770-736-8031 x56442',
'website': 'hildegard.org', website: 'hildegard.org',
'company': { company: {
'name': 'Romaguera-Crona', name: 'Romaguera-Crona',
'catchPhrase': 'Multi-layered client-server neural-net', catchPhrase: 'Multi-layered client-server neural-net',
'bs': 'harness real-time e-markets' bs: 'harness real-time e-markets'
} }
}) })
+18 -18
View File
@@ -1,23 +1,23 @@
window.users.push({ window.users.push({
'id': 2, id: 2,
'name': 'Ervin Howell', name: 'Ervin Howell',
'username': 'Antonette', username: 'Antonette',
'email': 'Shanna@melissa.tv', email: 'Shanna@melissa.tv',
'address': { address: {
'street': 'Victor Plains', street: 'Victor Plains',
'suite': 'Suite 879', suite: 'Suite 879',
'city': 'Wisokyburgh', city: 'Wisokyburgh',
'zipcode': '90566-7771', zipcode: '90566-7771',
'geo': { geo: {
'lat': '-43.9509', lat: '-43.9509',
'lng': '-34.4618' lng: '-34.4618'
} }
}, },
'phone': '010-692-6593 x09125', phone: '010-692-6593 x09125',
'website': 'anastasia.net', website: 'anastasia.net',
'company': { company: {
'name': 'Deckow-Crist', name: 'Deckow-Crist',
'catchPhrase': 'Proactive didactic contingency', catchPhrase: 'Proactive didactic contingency',
'bs': 'synergize scalable supply-chains' bs: 'synergize scalable supply-chains'
} }
}) })
+18 -18
View File
@@ -1,23 +1,23 @@
window.users.push({ window.users.push({
'id': 3, id: 3,
'name': 'Clementine Bauch', name: 'Clementine Bauch',
'username': 'Samantha', username: 'Samantha',
'email': 'Nathan@yesenia.net', email: 'Nathan@yesenia.net',
'address': { address: {
'street': 'Douglas Extension', street: 'Douglas Extension',
'suite': 'Suite 847', suite: 'Suite 847',
'city': 'McKenziehaven', city: 'McKenziehaven',
'zipcode': '59590-4157', zipcode: '59590-4157',
'geo': { geo: {
'lat': '-68.6102', lat: '-68.6102',
'lng': '-47.0653' lng: '-47.0653'
} }
}, },
'phone': '1-463-123-4447', phone: '1-463-123-4447',
'website': 'ramiro.info', website: 'ramiro.info',
'company': { company: {
'name': 'Romaguera-Jacobson', name: 'Romaguera-Jacobson',
'catchPhrase': 'Face to face bifurcated interface', catchPhrase: 'Face to face bifurcated interface',
'bs': 'e-enable strategic applications' bs: 'e-enable strategic applications'
} }
}) })
+18 -18
View File
@@ -1,23 +1,23 @@
window.users.push({ window.users.push({
'id': 4, id: 4,
'name': 'Patricia Lebsack', name: 'Patricia Lebsack',
'username': 'Karianne', username: 'Karianne',
'email': 'Julianne.OConner@kory.org', email: 'Julianne.OConner@kory.org',
'address': { address: {
'street': 'Hoeger Mall', street: 'Hoeger Mall',
'suite': 'Apt. 692', suite: 'Apt. 692',
'city': 'South Elvis', city: 'South Elvis',
'zipcode': '53919-4257', zipcode: '53919-4257',
'geo': { geo: {
'lat': '29.4572', lat: '29.4572',
'lng': '-164.2990' lng: '-164.2990'
} }
}, },
'phone': '493-170-9623 x156', phone: '493-170-9623 x156',
'website': 'kale.biz', website: 'kale.biz',
'company': { company: {
'name': 'Robel-Corkery', name: 'Robel-Corkery',
'catchPhrase': 'Multi-tiered zero tolerance productivity', catchPhrase: 'Multi-tiered zero tolerance productivity',
'bs': 'transition cutting-edge web services' bs: 'transition cutting-edge web services'
} }
}) })
+5 -5
View File
@@ -5,12 +5,12 @@ const {
processIf, processIf,
getBaseTransformPreset, getBaseTransformPreset,
createObjectExpression, createObjectExpression,
createObjectProperty, createObjectProperty
} = require('@vue/compiler-core') } = require('@vue/compiler-core')
const { parse } = require('@vue/compiler-dom') const { parse } = require('@vue/compiler-dom')
function headTransform(node, context) { function headTransform (node, context) {
console.log('NODE', node) console.log('NODE', node)
if (node.type === 1 /* NodeTypes.ELEMENT */) { if (node.type === 1 /* NodeTypes.ELEMENT */) {
return () => { return () => {
@@ -24,7 +24,7 @@ function headTransform(node, context) {
node.children.length === 1 ? node.children[0] : 'null' node.children.length === 1 ? node.children[0] : 'null'
) )
//options.properties.push(option) // options.properties.push(option)
} }
} }
} }
@@ -32,7 +32,7 @@ function headTransform(node, context) {
module.exports = function (source, map) { module.exports = function (source, map) {
// TODO: add options // TODO: add options
const ast = parse(source) const ast = parse(source)
//console.log('AST', ast) // console.log('AST', ast)
const [nodeTransforms, directiveTransforms] = getBaseTransformPreset({ const [nodeTransforms, directiveTransforms] = getBaseTransformPreset({
prefixIdentifiers: true prefixIdentifiers: true
@@ -49,7 +49,7 @@ module.exports = function (source, map) {
const result = generate(ast, { mode: 'module' }) const result = generate(ast, { mode: 'module' })
console.log(result.code) console.log(result.code)
this.callback(null, ` this.callback(null, `
import { computed } from 'vue' import { computed } from 'vue'
+1 -1
View File
@@ -77,6 +77,6 @@ setTimeout(() => {
setTimeout(() => { setTimeout(() => {
console.log('trigger app 4') console.log('trigger app 4')
const App = Vue.extend({ template: `<div>app 4</div>` }) const App = Vue.extend({ template: '<div>app 4</div>' })
new App().$mount() new App().$mount()
}, 10000) }, 10000)
+57
View File
@@ -0,0 +1,57 @@
<script>
import { h, ref, computed, inject, Teleport } from 'vue'
import { renderMeta } from './render'
export default {
props: {
metainfo: {
type: Object,
required: true
}
},
setup() {
const mapping = inject('__vueMetaConfig')
return {
mapping
}
},
render() {
const targets = {}
for (const key in this.metainfo) {
const config = this.mapping[key] || {}
const vnodes = renderMeta(this, key, this.metainfo[key], config)
let target = (key !== 'base' && this.metainfo[key].target) || config.target || 'head'
if (Array.isArray(vnodes)) {
for (const vnode of vnodes) {
if (vnode.__vm_target) {
target = vnode.__vm_target
delete vnode.__vm_target
}
if (!targets[target]) {
targets[target] = []
}
targets[target].push(vnode)
}
continue
}
if (!targets[target]) {
targets[target] = []
}
targets[target].push(vnodes)
continue
}
console.log('TARGETS', targets)
return Object.keys(targets).map(target => {
return h(Teleport, { to: target }, targets[target])
})
}
}
</script>
+119
View File
@@ -0,0 +1,119 @@
const defaults = {
title: {
contentAttributes: false
},
base: {
contentAttributes: [
'href',
'target'
]
},
meta: {
nameAttribute: 'name',
contentAttributes: [
'content',
'name',
'http-equiv',
'charset'
]
},
link: {
contentAttributes: [
'href',
'crossorigin',
'rel',
'media',
'integrity',
'hreflang',
'type',
'referrerpolicy',
'sizes',
'imagesrcset',
'imagesizes',
'as',
'color'
]
},
style: {
contentAttributes: [
'media'
]
},
script: {
contentAttributes: [
'src',
'type',
'nomodule',
'async',
'defer',
'crossorigin',
'integrity',
'referrerpolicy'
]
},
noscript: {
contentAttributes: false
}
}
const defaultMapping = {
body: {
tag: 'script',
target: 'body'
},
base: {
contentAttribute: 'href'
},
charset: {
tag: 'meta',
nameless: true,
contentAttribute: 'charset'
},
description: {
tag: 'meta'
},
og: {
group: true,
namespacedAttribute: true,
tag: 'meta',
nameAttribute: 'property'
},
twitter: {
group: true,
namespacedAttribute: true,
tag: 'meta'
}
}
export {
defaults,
defaultMapping
}
export function hasConfig (name) {
return !!defaults[name] || !!defaultMapping[name]
}
export function getConfigKey (name, key, config, dontLog) {
if (!dontLog) {
// console.log('getConfigKey', name, key, getConfigKey(name, key, config, true), config)
}
if (config && key in config) {
return config[key]
}
if (Array.isArray(name)) {
for (const _name of name) {
if (_name && _name in defaults) {
return defaults[_name][key]
}
}
}
if (name in defaults) {
return defaults[name][key]
}
return undefined
}
+18 -13
View File
@@ -1,24 +1,30 @@
import { markRaw, reactive, computed, onMounted } from 'vue' import { markRaw, reactive, onMounted } from 'vue'
import { defaultMapping } from './config'
const apps = {} const apps = {}
let appId = 1
export function createMeta () { export function createMeta ({ config }) {
const id = Symbol() const id = Symbol(`vue-meta-${appId++}`)
const Meta = { const Meta = {
id, id,
install(app) { install (app) {
let watchersAdded = false let watchersAdded = false
app.provide('__vueMetaConfig', {
...defaultMapping,
...config
})
app.mixin({ app.mixin({
created() { created () {
if (this === this.$root) { if (this === this.$root) {
watchersAdded = true watchersAdded = true
} }
if (!this.metaData) { if (!this.metaData || watchersAdded) {
return return
} }
@@ -33,7 +39,7 @@ export function createMeta () {
} }
} }
const __meta = markRaw({ this.__meta = markRaw({
depth depth
}) })
console.log('CREATED', this, this.metaData, depth) console.log('CREATED', this, this.metaData, depth)
@@ -49,15 +55,14 @@ export function createMeta () {
return Meta return Meta
} }
export function useMeta () { export function useMeta (rawMetainfo) {
onMounted(vmMounted) onMounted(vmMounted)
const metaData = reactive([]) const metainfo = reactive(rawMetainfo)
console.log(this)
return metaData return metainfo
} }
function vmMounted() { function vmMounted () {
console.log('MOUNTED', this, arguments) console.log('MOUNTED', this, arguments)
} }
+154
View File
@@ -0,0 +1,154 @@
import { h } from 'vue'
import { getConfigKey } from './config'
export function renderMeta (ctx, key, data, config) {
console.info('renderMeta', key, data, config)
if (config.group) {
return renderGroup(ctx, key, data, config)
}
return renderTag(ctx, key, data, config)
}
export function renderGroup (ctx, key, data, config) {
console.info('renderGroup', key, data, config)
if (Array.isArray(data)) {
config.contentAttributes = getConfigKey([key, config.tag], 'contentAttributes', config)
return data.map(_data => renderTag(ctx, key, _data, config))
}
return Object.keys(data).map((childKey) => {
const groupConfig = {
group: key,
data
}
if (config.namespaced || config.namespacedAttribute) {
let namespace
if (config.namespaced) {
namespace = config.namespaced === true ? key : config.namespaced
groupConfig.tagNamespace = namespace
} else {
namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute
groupConfig.fullName = `${namespace}:${childKey}`
groupConfig.slotName = `${namespace}(${childKey})`
}
}
return renderTag(ctx, key, data[childKey], config, groupConfig)
})
}
export function renderTag (ctx, key, data, config = {}, groupConfig = {}) {
if (!config.group && Array.isArray(data)) {
return renderTag(ctx, key, { content: data }, config, groupConfig)
}
const { tag = config.tag || key } = data
const {
slotName = key,
fullName = key
} = groupConfig
let content, hasChilds
if (Array.isArray(data)) {
return data.map((child) => {
return renderTag(ctx, key, child, config, groupConfig)
})
} else if (data.content && Array.isArray(data.content)) {
content = data.content.map((child) => {
if (typeof child === 'string') {
return child
}
return renderTag(ctx, key, child, config, groupConfig)
})
hasChilds = true
} else {
content = data
}
let { attrs: attributes } = data
if (!attributes && typeof data === 'object') {
attributes = {
...data
}
delete attributes.tag
delete attributes.content
delete attributes.target
} else {
attributes = {}
}
if (hasChilds) {
content = getSlotContent(ctx, slotName, content, config, data)
} else {
const contentAttributes = getConfigKey(tag, 'contentAttributes', config)
if (contentAttributes) {
if (!config.nameless) {
const nameAttribute = getConfigKey(tag, 'nameAttribute', config)
if (nameAttribute) {
attributes[nameAttribute] = fullName
}
}
const contentAttribute = config.contentAttribute || contentAttributes[0]
attributes[contentAttribute] = getSlotContent(ctx, slotName, attributes[contentAttribute] || content, config, groupConfig)
content = undefined
} else {
content = getSlotContent(ctx, slotName, content, config, data, true)
}
}
const finalTag = groupConfig.tagNamespace
? `${groupConfig.tagNamespace}:${tag}`
: tag
console.info('FINAL TAG', finalTag)
console.log(' ATTRIBUTES', attributes)
console.log(' CONTENT', content)
// console.log(data, attributes, config)
if (hasChilds) {
for (const child of content) {
if (typeof child === 'string') {
continue
}
if (child.type === finalTag) {
return content
}
break
}
}
const vnode = h(finalTag, attributes, content)
if (data.target) {
vnode.__vm_target = data.target
}
return vnode
}
export function getSlotContent ({ metainfo, $slots }, slotName, content, config, groupConfig) {
if (!$slots[slotName]) {
return content
}
const slotProps = {
content,
metainfo
}
if (groupConfig.group) {
slotProps[groupConfig.group] = groupConfig.data
}
content = $slots[slotName](slotProps)
return content[0].children
}
+5 -6
View File
@@ -1,11 +1,10 @@
import { createSSRApp } from 'vue' import { createSSRApp } from 'vue'
import { createRouter, createMemoryHistory } from 'vue-router' import { createRouter, createMemoryHistory } from 'vue-router'
import VueMeta from '../../'
/*Vue.use(Router) /* Vue.use(Router)
Vue.use(VueMeta, { Vue.use(VueMeta, {
tagIDKeyName: 'hid' tagIDKeyName: 'hid'
})*/ }) */
export default function createMyApp () { export default function createMyApp () {
const Home = { const Home = {
@@ -116,7 +115,7 @@ export default function createMyApp () {
users: process.server ? [] : window.users users: process.server ? [] : window.users
} }
}, },
mounted() { mounted () {
const { set, remove } = this.$meta().addApp('client-only') const { set, remove } = this.$meta().addApp('client-only')
set({ set({
bodyAttrs: { class: 'client-only' } bodyAttrs: { class: 'client-only' }
@@ -149,11 +148,11 @@ export default function createMyApp () {
app.use(router) app.use(router)
/*const { set } = app.$meta().addApp('custom') /* const { set } = app.$meta().addApp('custom')
set({ set({
bodyAttrs: { class: 'custom-app' }, bodyAttrs: { class: 'custom-app' },
meta: [{ charset: 'utf-8' }] meta: [{ charset: 'utf-8' }]
})*/ }) */
return { app, router } return { app, router }
} }
+4 -4
View File
@@ -1,8 +1,8 @@
import path from 'path' import path from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import template from 'lodash/template' import template from 'lodash/template'
const { renderToString } = require('@vue/server-renderer')
import createApp from './App' import createApp from './App'
const { renderToString } = require('@vue/server-renderer')
const templateFile = path.resolve(__dirname, 'app.template.html') const templateFile = path.resolve(__dirname, 'app.template.html')
const templateContent = fs.readFileSync(templateFile, { encoding: 'utf8' }) const templateContent = fs.readFileSync(templateFile, { encoding: 'utf8' })
@@ -18,12 +18,12 @@ export async function renderPage ({ url }) {
await router.push(url.substr(4)) await router.push(url.substr(4))
await router.isReady() await router.isReady()
/*console.log(router) /* console.log(router)
const matchedComponents = router.getMatchedComponents() const matchedComponents = router.getMatchedComponents()
// no matched routes, reject with 404 // no matched routes, reject with 404
if (!matchedComponents.length) { if (!matchedComponents.length) {
return reject({ code: 404 }) return reject({ code: 404 })
}*/ } */
const appHtml = await renderToString(app) const appHtml = await renderToString(app)
@@ -41,7 +41,7 @@ export async function renderPage ({ url }) {
head: () => {}, head: () => {},
bodyPrepend: () => {}, bodyPrepend: () => {},
bodyAppend: () => {} bodyAppend: () => {}
//...app.$meta().inject() // ...app.$meta().inject()
}) })
return pageHtml return pageHtml
+3 -2
View File
@@ -3,12 +3,13 @@
<p>Has metaInfo been updated due to navigation? {{ metaUpdated }}</p> <p>Has metaInfo been updated due to navigation? {{ metaUpdated }}</p>
</template> </template>
<script>
/*
<head type="template"> <head type="template">
<title v-if="title">{{ title }}</title> <title v-if="title">{{ title }}</title>
<meta v-for="meta in metas" :name="meta.name" :content="meta.content" /> <meta v-for="meta in metas" :name="meta.name" :content="meta.content" />
</head> </head>
*/
<script>
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
+103 -74
View File
@@ -1,27 +1,17 @@
import { createApp, defineComponent, reactive, toRefs, h, onMounted } from 'vue' import { createApp, defineComponent, reactive, toRefs, h } from 'vue'
import VueMeta from 'vue-meta'
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import About from './about.vue' import Metainfo from '../next/Metainfo.vue'
import { createMeta, useMeta } from '../next' import { createMeta, useMeta } from '../next'
import About from './about.vue'
/*Vue.use(VueMeta, {
refreshOnceOnNavigation: true
})*/
const meta = createMeta({
})
let metaUpdated = 'no' let metaUpdated = 'no'
const ChildComponent = defineComponent({ const ChildComponent = defineComponent({
name: 'child-component', name: 'child-component',
props: { props: {
page: String page: String
}, },
template: ` template: `
<metainfo>
<title>Another Title</title>
</metainfo>
<div> <div>
<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>
@@ -38,41 +28,20 @@ const ChildComponent = defineComponent({
} }
}, },
created () { created () {
console.log(this) //console.log(this)
}, },
setup () { setup () {
const metaData = useMeta({
})
const state = reactive({ const state = reactive({
date: null, date: null,
metaUpdated metaUpdated
}) })
onMounted(function vmMounted() {
console.log('MOUNTED', this, arguments)
})
return { return {
metaData,
...toRefs(state) ...toRefs(state)
} }
}, }
/*mounted () {
this.interval = setInterval(() => {
this.date = new Date()
}, 1000)
},
destroyed () {
clearInterval(this.interval)
}*/
}) })
// this wrapper function is not a requirement for vue-router,
// just a demonstration that render-function style components also work.
// See https://github.com/nuxt/vue-meta/issues/9 for more info.
function view (page) { function view (page) {
return { return {
name: `section-${page}`, name: `section-${page}`,
@@ -82,6 +51,86 @@ function view (page) {
} }
} }
const App = {
setup () {
const metainfo = useMeta({
base: { href: '/vue-router', target: '_blank' },
charset: 'utf8',
title: 'My Title',
description: 'The Description',
og: {
title: 'Og Title',
description: 'Bla bla',
image: [
'https://picsum.photos/600/400/?image=80',
'https://picsum.photos/600/400/?image=82'
]
},
twitter: {
title: 'Twitter Title'
},
noscript: [
'<!-- // A code comment -->',
{ tag: 'link', rel: 'stylesheet', href: 'style.css' }
],
otherNoscript: {
tag: 'noscript',
'data-test': 'hello',
content: [
'<!-- // Another code comment -->',
{ tag: 'link', rel: 'stylesheet', href: 'style2.css' }
]
},
body: 'body-script1.js',
script: [
'<!--[if IE]>',
{ src: 'head-script1.js' },
'<![endif]>',
{ src: 'body-script2.js', target: 'body' },
{ src: 'body-script3.js', target: '#put-it-here' }
],
esi: {
content: [{
tag: 'choose',
content: [{
tag: 'when',
test: '$(HTTP_COOKIE{group})=="Advanced"',
content: [{
tag: 'include',
src: 'http://www.example.com/advanced.html'
}]
}]
}]
}
})
setTimeout(() => (metainfo.title = 'My Updated Title'), 2000)
return {
metainfo
}
},
template: `
<metainfo :metainfo="metainfo">
<template v-slot:base="{ content, metainfo }">http://nuxt.dev:3000{{ content }}</template>
<template v-slot:title="{ content, metainfo }">{{ content }} - {{ metainfo.description }} - Hello</template>
<template v-slot:og(title)="{ content, metainfo, og }">
{{ content }} - {{ og.description }} - {{ metainfo.description }} - Hello Again
</template>
</metainfo>
<div id="app">
<h1>vue-router</h1>
<router-link to="/">Home</router-link>
<!-- router-link to="/about">About</router-link -->
<transition name="page" mode="out-in">
<router-view></router-view>
</transition>
<p>Inspect Element to see the meta info</p>
</div>
`
}
const router = createRouter({ const router = createRouter({
history: createWebHistory('/vue-router'), history: createWebHistory('/vue-router'),
routes: [ routes: [
@@ -90,45 +139,27 @@ const router = createRouter({
] ]
}) })
const Metadata = { const meta = createMeta({
template: ` config: {
<teleport to="head"> esi: {
<slot /> group: true,
</teleport> namespaced: true,
contentAttributes: [
<teleport to="body"> 'src',
<slot name="body" /> 'test',
</teleport> 'text'
` ]
} }
}
const App = { })
template: `
<metainfo>
<title>My Title</title>
<meta name="charset" content="utf8" />
<template v-slot:body>
<script>var a = 1</script>
</template>
</metainfo>
<div id="app">
<h1>vue-router</h1>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<transition name="page" mode="out-in">
<router-view></router-view>
</transition>
<p>Inspect Element to see the meta info</p>
</div>
`
}
const app = createApp(App) const app = createApp(App)
app.component('metainfo', Metadata) app.component('metainfo', Metainfo)
app.use(router) app.use(router)
app.use(meta) app.use(meta)
app.mount('#app')
// old stuff:
/* /*
const { set, remove } = app.$meta().addApp('custom') const { set, remove } = app.$meta().addApp('custom')
@@ -142,8 +173,6 @@ set({
}) })
setTimeout(() => remove(), 3000) setTimeout(() => remove(), 3000)
*/ */
app.mount('#app')
/* /*
const waitFor = time => new Promise(r => setTimeout(r, time || 1000)) const waitFor = time => new Promise(r => setTimeout(r, time || 1000))
const o = { const o = {
+1
View File
@@ -14,6 +14,7 @@
<body> <body>
<a href="/">&larr; Examples index</a> <a href="/">&larr; Examples index</a>
<div id="app"></div> <div id="app"></div>
<div id="put-it-here"></div>
<script src="/__build__/vue-router.js"></script> <script src="/__build__/vue-router.js"></script>
</body> </body>
</html> </html>
+2 -2
View File
@@ -4,7 +4,7 @@ import webpack from 'webpack'
import WebpackBar from 'webpackbar' import WebpackBar from 'webpackbar'
import { VueLoaderPlugin } from 'vue-loader' import { VueLoaderPlugin } from 'vue-loader'
const srcDir = path.join(__dirname, '..', 'src') // const srcDir = path.join(__dirname, '..', 'src')
export default { export default {
devtool: 'inline-source-map', devtool: 'inline-source-map',
@@ -63,7 +63,7 @@ export default {
// is a simple `export * from '@vue/runtime-dom`. However having this // is a simple `export * from '@vue/runtime-dom`. However having this
// extra re-export somehow causes webpack to always invalidate the module // extra re-export somehow causes webpack to always invalidate the module
// on the first HMR update and causes the page to reload. // on the first HMR update and causes the page to reload.
'vue': 'vue/dist/vue.esm.js', vue: 'vue/dist/vue.esm-bundler.js',
'vue-meta': path.resolve(__dirname, './next/') 'vue-meta': path.resolve(__dirname, './next/')
} }
}, },
+1 -1
View File
@@ -49,7 +49,7 @@
"dev": "cd examples && yarn dev && cd ..", "dev": "cd examples && yarn dev && cd ..",
"docs": "vuepress dev --host 0.0.0.0 --port 3000 docs", "docs": "vuepress dev --host 0.0.0.0 --port 3000 docs",
"docs:build": "vuepress build docs", "docs:build": "vuepress build docs",
"lint": "eslint src test", "lint": "eslint src test examples",
"prerelease": "git checkout master && git pull -r", "prerelease": "git checkout master && git pull -r",
"release": "yarn lint && yarn test && standard-version", "release": "yarn lint && yarn test && standard-version",
"test": "yarn test:unit && yarn test:e2e-ssr && yarn test:e2e-browser", "test": "yarn test:unit && yarn test:e2e-ssr && yarn test:e2e-browser",