Skip to content

Commit

Permalink
feat(vue): new Vue 2, Options Mixin install
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Sep 10, 2023
1 parent e4809d8 commit 3d422d6
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 8 deletions.
27 changes: 21 additions & 6 deletions docs/content/1.setup/4.vue/0.installation.md
Expand Up @@ -43,11 +43,11 @@ app.mount('#app')

```ts [Vue 2]
import Vue from 'vue'
import { Vue2ProvideUnheadPlugin, createHead } from '@unhead/vue'
import { createHead } from '@unhead/vue'
import { UnheadPlugin } from '@unhead/vue/vue2'

const head = createHead()
Vue.use(Vue2ProvideUnheadPlugin, head)
Vue.use(head)
Vue.mixin(UnheadPlugin(head))

new Vue({
el: '#app',
Expand All @@ -58,7 +58,9 @@ new Vue({

3. Done! Now you can use the `useHead` composable to manage your head.

```vue [app.vue]
::code-group

```vue [useHead]
<script setup lang=ts>
import { useHead } from '@unhead/vue'
Expand All @@ -67,6 +69,19 @@ useHead({
})
</script>
```

```vue [Options API]
<script>
export default {
head: {
title: 'My awesome site'
}
}
</script>
```

::

## Optional: Auto-Imports

Unhead provides out-of-the-box configuration for [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import).
Expand All @@ -86,9 +101,9 @@ export default defineConfig({
```


## Optional: Options API Mixin
## Optional: Vue 3 Options API

If you prefer using the options API, you will need to use the `VueHeadMixin` mixin.
The options API functionality is only provided out-of-the-box for Vue 2, if you'd like to use in Vue 3 you will need to install the mixin.

```ts
import { createApp } from 'vue'
Expand Down
1 change: 1 addition & 0 deletions packages/vue/build.config.ts
Expand Up @@ -11,5 +11,6 @@ export default defineBuildConfig({
entries: [
{ input: 'src/index', name: 'index' },
{ input: 'src/VueUseHeadPolyfill', name: 'polyfill' },
{ input: 'src/vue2/index', name: 'vue2' },
],
})
5 changes: 5 additions & 0 deletions packages/vue/package.json
Expand Up @@ -25,6 +25,11 @@
"types": "./dist/polyfill.d.ts",
"import": "./dist/polyfill.mjs",
"require": "./dist/polyfill.cjs"
},
"./vue2": {
"types": "./dist/vue2.d.ts",
"import": "./dist/vue2.mjs",
"require": "./dist/vue2.cjs"
}
},
"main": "dist/index.cjs",
Expand Down
4 changes: 3 additions & 1 deletion packages/vue/src/Vue2ProvideUnheadPlugin.ts
@@ -1,7 +1,9 @@
import type { Plugin } from 'vue'
import { headSymbol } from './createHead'

// TODO export under own subdirectory (vue2)
/**
* @deprecated Import { UnheadPlugin } from `@unhead/vue/vue2` and use Vue.mixin(UnheadPlugin(head)) instead.
*/
export const Vue2ProvideUnheadPlugin: Plugin = function (_Vue, head) {
// copied from https://github.com/vuejs/pinia/blob/v2/packages/pinia/src/vue2-plugin.ts
_Vue.mixin({
Expand Down
4 changes: 3 additions & 1 deletion packages/vue/src/VueHeadMixin.ts
Expand Up @@ -2,7 +2,9 @@ import { getCurrentInstance } from 'vue'
import { Vue3 } from './env'
import { useHead } from '.'

// TODO export under own subdirectory (vue2)
/**
* @deprecated No longer needed for Vue2 if using UnheadPlugin. Import { HeadOptions } from `@unhead/vue/vue2` and use Vue.mixin(HeadOptions) instead.
*/
export const VueHeadMixin = {
created() {
let source = false
Expand Down
58 changes: 58 additions & 0 deletions packages/vue/src/vue2/index.ts
@@ -0,0 +1,58 @@
import { getCurrentInstance } from 'vue/dist/vue'
import { headSymbol } from '../createHead'
import { useHead } from '../composables/useHead'
import type { VueHeadClient } from '../types'
import { Vue3 } from '../env'

export const HeadOptions = {
created() {
let source = false
if (Vue3) {
const instance = getCurrentInstance()
if (!instance)
return
const options = instance.type
if (!options || !('head' in options))
return

source = typeof options.head === 'function'
? () => options.head.call(instance.proxy)
: options.head
}
else {
// @ts-expect-error vue 2
const head = this.$options.head
if (head) {
source = typeof head === 'function'
? () => head.call(this)
: head
}
}

// @ts-expect-error vue 2
source && useHead(source)
},
}

export function UnheadPlugin(head: VueHeadClient<any>) {
return {
...HeadOptions,
beforeCreate() {
// @ts-expect-error vue 2
const options = this.$options
const origProvide = options.provide
options.provide = function () {
let origProvideResult
if (typeof origProvide === 'function')
origProvideResult = origProvide.call(this)
else
origProvideResult = origProvide || {}

return {
...origProvideResult,
[headSymbol]: head,
}
}
},
}
}

0 comments on commit 3d422d6

Please sign in to comment.