feat: add `nuxt-head` component (#166)

This commit is contained in:
Daniel Roe 2021-03-17 09:18:32 +00:00 committed by GitHub
parent 451fc29b60
commit 545bfe4f9e
3 changed files with 79 additions and 13 deletions

View File

@ -1,13 +0,0 @@
import type { Plugin } from 'nuxt/app'
import { createHead, renderHeadToString } from '@vueuse/head'
export default <Plugin> function head (nuxt) {
const { app, ssrContext } = nuxt
const head = createHead()
app.use(head)
if (process.server) {
ssrContext.head = () => renderHeadToString(head)
}
}

View File

@ -0,0 +1,56 @@
import { defineComponent } from '@vue/runtime-core'
import { useHead, HeadObject } from '@vueuse/head'
type MappedProps<T extends Record<string, any>> = {
[P in keyof T]: { type: () => T[P] }
}
const props: MappedProps<HeadObject> = {
base: { type: Object },
bodyAttrs: { type: Object },
htmlAttrs: { type: Object },
link: { type: Array },
meta: { type: Array },
script: { type: Array },
style: { type: Array },
title: { type: String }
}
export const Head = defineComponent({
props,
setup (props, { slots }) {
useHead(() => props)
return () => slots.default?.()
}
})
const createHeadComponent = (prop: keyof typeof props, isArray = false) =>
defineComponent({
setup (_props, { attrs, slots }) {
useHead(() => ({
[prop]: isArray ? [attrs] : attrs
}))
return () => slots.default?.()
}
})
const createHeadComponentFromSlot = (prop: keyof typeof props) =>
defineComponent({
setup (_props, { slots }) {
useHead(() => ({
[prop]: slots.default?.()[0]?.children
}))
return () => null
}
})
export const Html = createHeadComponent('htmlAttrs')
export const Body = createHeadComponent('bodyAttrs')
export const Title = createHeadComponentFromSlot('title')
export const Meta = createHeadComponent('meta', true)
export const Link = createHeadComponent('link', true)
export const Script = createHeadComponent('script', true)
export const Style = createHeadComponent('style', true)

View File

@ -0,0 +1,23 @@
import type { Plugin } from 'nuxt/app'
import { createHead, renderHeadToString } from '@vueuse/head'
import { Head, Html, Body, Title, Meta, Link, Script, Style } from './head'
export default <Plugin> function head (nuxt) {
const { app, ssrContext } = nuxt
const head = createHead()
app.use(head)
app.component('NuxtHead', Head)
app.component('NuxtHtml', Html)
app.component('NuxtBody', Body)
app.component('NuxtTitle', Title)
app.component('NuxtMeta', Meta)
app.component('NuxtHeadLink', Link)
app.component('NuxtScript', Script)
app.component('NuxtStyle', Style)
if (process.server) {
ssrContext.head = () => renderHeadToString(head)
}
}