Skip to content

Commit

Permalink
feat: add plugin for options api support
Browse files Browse the repository at this point in the history
  • Loading branch information
pimlie committed Jun 6, 2021
1 parent b802766 commit 0745f16
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 21 deletions.
6 changes: 0 additions & 6 deletions dist/vue-meta-ssr.d.ts

This file was deleted.

1 change: 1 addition & 0 deletions examples/vue-router/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export default {
<ul class="menu">
<li><router-link to="/">Home</router-link></li>
<li><router-link to="/about">About</router-link></li>
<li><router-link to="/options">Options</router-link></li>
</ul>
<router-view v-slot="{ Component }" class="page">
Expand Down
6 changes: 6 additions & 0 deletions examples/vue-router/Options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
metaInfo: {
title: 'Title from Options API'
},
template: '<div>This component uses the Options API</div>'
}
5 changes: 5 additions & 0 deletions examples/vue-router/Child.ts → examples/vue-router/Page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ let metaUpdated = 'no'

export default defineComponent({
name: 'ChildComponent',
metaInfo () {
return {
title: 'asdf'
}
},
setup () {
const route = useRoute()

Expand Down
15 changes: 9 additions & 6 deletions examples/vue-router/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { h, createApp as createVueApp, createSSRApp } from 'vue'
import { createRouter as createVueRouter, createMemoryHistory, createWebHistory } from 'vue-router'
import { createMetaManager as createVueMetaManager, defaultConfig, useMeta } from '../../src'
import { createMetaManager as createVueMetaManager, defaultConfig, useMeta, plugin } from '../../src'
import * as deepestResolver from '../../src/resolvers/deepest'
import App from './App'
import ChildComponent from './Child'
import PageComponent from './Page'
import PageOptions from './Options'

function createComponent () {
function createPage () {
return {
render: () => h(ChildComponent)
render: () => h(PageComponent)
}
}
/*
Expand All @@ -34,8 +35,9 @@ const createMetaManager = (isSSR = false) => createVueMetaManager(
const createRouter = (base: string, isSSR = false) => createVueRouter({
history: isSSR ? createMemoryHistory(base) : createWebHistory(base),
routes: [
{ name: 'home', path: '/', component: createComponent() },
{ name: 'about', path: '/about', component: createComponent() }
{ name: 'home', path: '/', component: createPage() },
{ name: 'about', path: '/about', component: createPage() },
{ name: 'options', path: '/options', component: PageOptions }
]
})

Expand All @@ -46,6 +48,7 @@ const createApp = (base: string, isSSR = null) => {

app.use(router)
app.use(metaManager)
app.use(plugin)

useMeta(
{
Expand Down
5 changes: 5 additions & 0 deletions examples/vue-shims.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module '*.vue' {
import { ComponentOptions } from 'vue'
const component: ComponentOptions
export default component
}
8 changes: 4 additions & 4 deletions examples/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ module.exports = (isBrowser) => {
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.vue$/,
use: 'vue-loader'
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"@types/webpack-env": "^1.16.0",
"@typescript-eslint/eslint-plugin": "^4.15.2",
"@typescript-eslint/parser": "^4.15.2",
"@vue/compiler-sfc": "^3.0.6",
"@vue/compiler-sfc": "^3.0.11",
"@vue/server-renderer": "^3.0.6",
"@vue/test-utils": "^2.0.0-rc.6",
"@wishy-gift/html-include-chunks-webpack-plugin": "^0.1.5",
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as deepestResolver from './resolvers/deepest'

export { defaultConfig } from './config'
export { createMetaManager } from './manager'
export { install as plugin } from './plugin'
export { resolveOption } from './resolvers'

export * from './types'
export * from './useApi'

Expand Down
35 changes: 35 additions & 0 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { isFunction } from '@vue/shared'
import { App, ComponentOptionsMixin, computed, getCurrentInstance } from 'vue'
import { ComponentOptionsMetaInfo } from './types/options'
import { useMeta } from './useApi'

export type PluginOptions = {
keyName: string
}

export const defaultOptions: PluginOptions = {
keyName: 'metaInfo'
}

type CreateMixin = (options: PluginOptions) => ComponentOptionsMixin
export const createMixin: CreateMixin = options => ({
created () {
const instance = getCurrentInstance()
if (!instance?.type || !(options.keyName in instance.type)) {
return
}

const metaInfo = (instance.type as any)[options.keyName] as ComponentOptionsMetaInfo
if (isFunction(metaInfo)) {
const computedMetaInfo = computed(metaInfo)
useMeta(computedMetaInfo)
} else {
useMeta(metaInfo)
}
}
})

export const install = (app: App, _options: Partial<PluginOptions> = {}) => {
const options = Object.assign({}, defaultOptions, _options)
app.mixin(createMixin(options))
}
5 changes: 5 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ComponentOptionsMetaInfo } from './options'
import type { VNode, Slots, ComponentInternalInstance } from 'vue'
import type { MergedObject, ResolveContext, ResolveMethod } from '../object-merge'
import type { MetaManager } from '../manager'
Expand Down Expand Up @@ -118,4 +119,8 @@ declare module '@vue/runtime-core' {
$metaManager: MetaManager
$metaGuards: MetaGuards
}

interface ComponentCustomOptions {
metaInfo?: ComponentOptionsMetaInfo
}
}
137 changes: 137 additions & 0 deletions src/types/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
export interface AttributeProperty {
[key: string]: string | string[]
}

export interface MetaDataProperty {
vmid?: string,
once?: boolean,
skip?: boolean,
body?: boolean,
pbody?: boolean,
[key: string]: any
}

export interface MetaPropertyCharset extends MetaDataProperty {
charset: string,
}

export interface MetaPropertyEquiv extends MetaDataProperty {
httpEquiv: string,
content: string,
}

export interface MetaPropertyTrueEquiv extends MetaDataProperty {
'http-equiv': string,
content: string,
}

export interface MetaPropertyName extends MetaDataProperty {
name: string,
content: string,
}

export interface MetaPropertyMicrodata extends MetaDataProperty {
itemprop: string,
content: string,
}

// non-w3c interface
export interface MetaPropertyProperty extends MetaDataProperty {
property: string,
content: string,
}

export interface LinkPropertyBase extends MetaDataProperty {
rel: string,
crossOrigin?: string | null,
media?: string,
nonce?: string,
referrerPolicy?: string,
rev?: string,
type?: string
}

export interface LinkPropertyHref extends LinkPropertyBase {
href?: string,
hreflang?: string,
callback?: void
}

export interface LinkPropertyHrefCallback extends LinkPropertyBase {
vmid: string,
// callback: CallbackFn,
href?: string,
hreflang?: string
}

export interface StyleProperty extends MetaDataProperty {
cssText: string,
// callback?: CallbackFn
media?: string,
nonce?: string,
type?: string,
}

export interface ScriptPropertyBase extends MetaDataProperty {
type?: string,
charset?: string,
async?: boolean,
defer?: boolean,
crossOrigin?: string,
nonce?: string
}

export interface ScriptPropertyText extends ScriptPropertyBase {
innerHTML: string
}

export interface ScriptPropertySrc extends ScriptPropertyBase {
src: string,
callback?: void
}

export interface ScriptPropertySrcCallback extends ScriptPropertyBase {
vmid: string,
// callback: CallbackFn
}

// eslint-disable-next-line no-use-before-define
type JsonVal = string | number | boolean | JsonObj | JsonObj[] | null

interface JsonObj {
[key: string]: JsonVal | JsonVal[]
}

export interface ScriptPropertyJson extends ScriptPropertyBase {
json: JsonObj
}

export interface NoScriptProperty extends MetaDataProperty {
innerHTML: string,
}

export interface ComponentMetaInfo {
title?: string

htmlAttrs?: AttributeProperty
headAttrs?: AttributeProperty
bodyAttrs?: AttributeProperty

base?: {
target: string,
href: string
}

meta?: (MetaPropertyCharset | MetaPropertyEquiv | MetaPropertyTrueEquiv | MetaPropertyName | MetaPropertyMicrodata | MetaPropertyProperty)[]
link?: (LinkPropertyBase | LinkPropertyHref | LinkPropertyHrefCallback)[]
style?: StyleProperty[]
script?: (ScriptPropertyText | ScriptPropertySrc | ScriptPropertySrcCallback | ScriptPropertyJson)[]
noscript?: NoScriptProperty[]

__dangerouslyDisableSanitizers?: string[]
__dangerouslyDisableSanitizersByTagID?: {
[key: string]: string[]
}
}

export type ComponentOptionsMetaInfo = ComponentMetaInfo | (() => ComponentMetaInfo)
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
}
},
"include": [
"src/global.d.ts",
"src/**/*.ts",
"test/**/*.ts"
"test/**/*.ts",
"examples/**/*.ts",
"examples/**/*.vue"
],
}
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@
"@vue/compiler-core" "3.0.11"
"@vue/shared" "3.0.11"

"@vue/compiler-sfc@^3.0.6":
"@vue/compiler-sfc@^3.0.11":
version "3.0.11"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.11.tgz#cd8ca2154b88967b521f5ad3b10f5f8b6b665679"
integrity sha512-7fNiZuCecRleiyVGUWNa6pn8fB2fnuJU+3AGjbjl7r1P5wBivfl02H4pG+2aJP5gh2u+0wXov1W38tfWOphsXw==
Expand Down

0 comments on commit 0745f16

Please sign in to comment.