mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 21:25:11 +00:00
feat: add nuxt-head
component (#166)
This commit is contained in:
parent
451fc29b60
commit
545bfe4f9e
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
56
packages/nuxt3/src/app/plugins/head/head.ts
Normal file
56
packages/nuxt3/src/app/plugins/head/head.ts
Normal 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)
|
23
packages/nuxt3/src/app/plugins/head/index.ts
Normal file
23
packages/nuxt3/src/app/plugins/head/index.ts
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user