帮我把 @unhead/vue 的版本升级到 v2.0.2
--- title: Migrate Your TypeScript App To Unhead v2 description: Learn about how to migrate to TypeScript Unhead v2 from v1. navigation: title: Upgrade Guide --- ## Introduction With the release of Unhead v2, we now have first-class support for other frameworks. However, this guide will focus on the changes that affec TypeScript users. The high-level of Unhead v2 was to remove deprecations and remove the implicit context implementation. ### Legacy Support Unhead v2 is mostly fully backwards compatible with Unhead v1. While not recommended, if upgrading is not possible for you, you can change your imports to the following: ```diff [TypeScript] -import { createServerHead, useHead } from 'unhead' +import { createServerHead, useHead } from 'unhead/legacy' ``` This will be removed in a future minor version, so you should lock your dependencies to the version that works for you. ## Client / Server Subpath Exports 🚦 Impact Level: Critical **⚠️ Breaking Changes:** - `createServerHead()`{lang="ts"} and `createHead()`{lang="ts"} exports from `unhead` are removed The path where you import `createHead` from has been updated to be a subpath export. Please follow the updated installation instructions or simply update the import to use the subpath. **Client bundle:** ```diff -import { createServerHead } from 'unhead' +import { createHead } from 'unhead/client' // avoids bundling server plugins createHead() ``` **Server bundle:** ```diff -import { createServerHead } from 'unhead' +import { createHead } from 'unhead/server' // avoids bundling server plugins -createServerHead() +createHead() ``` ## Removed Implicit Context 🚦 Impact Level: Critical **⚠️ Breaking Changes:** - `getActiveHead()`{lang="ts"}, `activeHead`{lang="ts"} exports are removed The implicit context implementation kept a global instance of Unhead available so that you could use the `useHead()`{lang="ts"} composables anywhere in your application. ```ts useHead({ title: 'This just worked!' }) ``` While safe client side, this was a leaky abstraction server side and led to memory leaks in some cases. In v2, the core composables no longer have access to the Unhead instance. Instead, you must pass the Unhead instance to the composables. ::note Passing the instance is only relevant if you're importing from `unhead`. In JavaScript frameworks we tie the context to the framework itself so you don't need to worry about this. :: ::code-group ```ts [TypeScript v2] import { useHead } from 'unhead' // example of getting the instance const unheadInstance = useMyApp().unhead useHead(unheadInstance, { title: 'Looks good' }) ``` ```ts [TypeScript v1] import { useHead } from 'unhead' useHead({ title: 'Just worked! But with SSR issues' }) ``` :: ## Removed `vmid`, `hid`, `children`, `body` 🚦 Impact Level: High For legacy support with Vue Meta we allowed end users to provide deprecated properties: `vmid`, `hid`, `children` and `body`. You must either update these properties to the appropriate replacement, remove them, or you can use the `DeprecationsPlugin`. **Meta tags with `vmid`, `hid`** These are already deduped magically so you can safely remove them there. ```diff useHead({ meta: [{ name: 'description', - vmid: 'description' - hid: 'description' }] }) ``` **Other Tags with `vmid`, `hid`** Use `key` if you need the deduplication feature. This is useful for tags that may change from server to client rendering. ```diff useHead({ script: [{ - vmid: 'my-key' - hid: 'my-key' + key: 'my-key', }] }) ``` **Using `children`** The `children` key is a direct replacement of `innerHTML` which you should use instead. ::Caution When migrating your code ensure that you're not dynamically setting `innerHTML` as this can lead to XSS vulnerabilities. :: ```diff useHead({ script: [ { - children: '..' + innerHTML: '..' } ] }) ``` **Using `body`** The `body` key should be updated to use the Tag Position feature. ```diff useHead({ script: [ { - body: true + tagPosition: 'bodyClose' } ] }) ``` **Use Deprecations Plugin** ```ts import { createHead } from 'unhead' import { DeprecationsPlugin } from 'unhead/plugins' const unhead = createHead({ plugins: [DeprecationsPlugin] }) ``` ## Opt-in Template Params & Tag Alias Sorting 🚦 Impact Level: High To reduce the bundle size and improve performance, we've moved the template params and tag alias sorting to optional plugins. If you'd like to continue using these, please opt-in to the plugins. ```ts import { AliasSortingPlugin, TemplateParamsPlugin } from 'unhead/plugins' createHead({ plugins: [TemplateParamsPlugin, AliasSortingPlugin] }) ``` ## Vue 2 Support 🚦 Impact Level: Critical Unhead v2 no longer supports Vue v2. If you're using Vue v2, you will need to lock your dependencies to the latest v1 version of Unhead. ## Promise Input Support 🚦 Impact Level: Medium If you have promises as input they will no longer be resolved, either await the promise before passing it along or register the optional promises plugin. **Option 1: Await Promise** ```diff useHead({ link: [ { - href: import('~/assets/MyFont.css?url'), + href: await import('~/assets/MyFont.css?url'), rel: 'stylesheet', type: 'text/css' } ] }) ``` **Option 2: Promise Plugin** ```ts import { PromisePlugin } from 'unhead/plugins' const unhead = createHead({ plugins: [PromisePlugin] }) ``` ## Updated `useScript()`{lang="ts"} 🚦 Impact Level: High **⚠️ Breaking Changes:** - Script instance is no longer augmented as a proxy and promise - `script.proxy`{lang="ts"} is rewritten for simpler, more stable behavior - `stub()`{lang="ts"} and runtime hook `script:instance-fn` are removed **Replacing promise usage** If you're using the script as a promise you should instead opt to use the `onLoaded()` functions. ```diff const script = useScript() -script.then(() => console.log('loaded') +script.onLoaded(() => console.log('loaded')) ``` **Replacing proxy usage** If you're accessing the underlying API directly from the script instance, you will now need to only access it from the `.proxy`. ```diff const script = useScript('..', { use() { return { foo: [] } } }) -script.foo.push('bar') +script.proxy.foo.push('bar') ``` **Replacing `stub()`** If you were using stub for anything you should replace this with either custom `use()` behavior. ```diff const script = useScript('...', { - stub() { return { foo: import.meta.server ? [] : undefined } } }) +script.proxy = {} // your own implementation ``` ## Tag Sorting Updated 🚦 Impact Level: :UBadge{color="success" variant="subtle" size="sm" label="Low"} An optional [Capo.js](https://rviscomi.github.io/capo.js/) plugin was added to Unhead, in v2 we make this the default sorting behavior. ::warning As all head tags may be re-ordered this will break any snapshot tests that you have in place and in some rare cases may lead to performance regressions. :: You can opt-out of Capo.js sorting by providing the option. ```ts createHead({ disableCapoSorting: true, }) ``` ## Default SSR Tags 🚦 Impact Level: Low When SSR Unhead will now insert important default tags for you: - `<meta charset="utf-8">` - `<meta name="viewport" content="width=device-width, initial-scale=1">` - `<html lang="en">` If you were previously relying on these being left empty, you may need to either disable them by using `disableDefaultTags` or insert tags to override them. ```ts import { createHead, useHead } from 'unhead/server' // disable when creating the head instance const head = createHead({ disableDefaults: true, }) useHead(head, { htmlAttrs: { lang: 'fr' } }) ``` ## CJS Exports Removed 🚦 Impact Level: Low CommonJS exports have been removed in favor of ESM only. ```diff -const { createHead } = require('unhead/client') +import { createHead } from 'unhead/client' ``` ## Deprecated `@unhead/schema` 🚦 Impact Level: Low The `@unhead/schema` package is now deprecated and will be removed in a future version. You should instead import the schema from `unhead/types` or `unhead`. ```diff -import { HeadTag } from '@unhead/schema' +import { HeadTag } from 'unhead/types' ```
This commit is contained in:
@ -44,7 +44,7 @@
|
||||
"@intlify/unplugin-vue-i18n": "^6.0.3",
|
||||
"@pinia/colada": "^0.13.5",
|
||||
"@primeuix/themes": "^1.0.0",
|
||||
"@unhead/vue": "^1.11.18",
|
||||
"@unhead/vue": "^2.0.2",
|
||||
"@vant/use": "^1.6.0",
|
||||
"@vueuse/core": "^13.0.0",
|
||||
"alova": "^3.2.8",
|
||||
|
59
pnpm-lock.yaml
generated
59
pnpm-lock.yaml
generated
@ -29,8 +29,8 @@ importers:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
'@unhead/vue':
|
||||
specifier: ^1.11.18
|
||||
version: 1.11.18(vue@3.5.13(typescript@5.8.2))
|
||||
specifier: ^2.0.2
|
||||
version: 2.0.2(vue@3.5.13(typescript@5.8.2))
|
||||
'@vant/use':
|
||||
specifier: ^1.6.0
|
||||
version: 1.6.0(vue@3.5.13(typescript@5.8.2))
|
||||
@ -1546,19 +1546,10 @@ packages:
|
||||
resolution: {integrity: sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@unhead/dom@1.11.18':
|
||||
resolution: {integrity: sha512-zQuJUw/et9zYEV0SZWTDX23IgurwMaXycAuxt4L6OgNL0T4TWP3a0J/Vm3Q02hmdNo/cPKeVBrwBdnFUXjGU4w==}
|
||||
|
||||
'@unhead/schema@1.11.18':
|
||||
resolution: {integrity: sha512-a3TA/OJCRdfbFhcA3Hq24k1ZU1o9szicESrw8DZcGyQFacHnh84mVgnyqSkMnwgCmfN4kvjSiTBlLEHS6+wATw==}
|
||||
|
||||
'@unhead/shared@1.11.18':
|
||||
resolution: {integrity: sha512-OsupRQRxJqqnuKiL1Guqipjbl7MndD5DofvmGa3PFGu2qNPmOmH2mxGFjRBBgq2XxY1KalIHl/2I9HV6gbK8cw==}
|
||||
|
||||
'@unhead/vue@1.11.18':
|
||||
resolution: {integrity: sha512-Jfi7t/XNBnlcauP9UTH3VHBcS69G70ikFd2e5zdgULLDRWpOlLs1sSTH1V2juNptc93DOk9RQfC5jLWbLcivFw==}
|
||||
'@unhead/vue@2.0.2':
|
||||
resolution: {integrity: sha512-pUGcbmPNCALOVWnQRtIjJ5ubNaZus3nHfCBDPEVwhbiLzeLF6wbhgTakwksZ1EegKNOZwRAkmVbV6i+23OYEUQ==}
|
||||
peerDependencies:
|
||||
vue: '>=2.7 || >=3'
|
||||
vue: '>=3.5.13'
|
||||
|
||||
'@unocss/astro@66.0.0':
|
||||
resolution: {integrity: sha512-GBhXT6JPqXjDXoJZTXhySk83NgOt0UigChqrUUdG4x7Z+DVYkDBION8vZUJjw0OdIaxNQ4euGWu4GDsMF6gQQg==}
|
||||
@ -3979,9 +3970,6 @@ packages:
|
||||
package-manager-detector@0.2.8:
|
||||
resolution: {integrity: sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==}
|
||||
|
||||
packrup@0.1.2:
|
||||
resolution: {integrity: sha512-ZcKU7zrr5GlonoS9cxxrb5HVswGnyj6jQvwFBa6p5VFw7G71VAHcUKL5wyZSU/ECtPM/9gacWxy2KFQKt1gMNA==}
|
||||
|
||||
page-stack-vue3@2.5.6:
|
||||
resolution: {integrity: sha512-X3POhyhkmtVski4cqM8lNW1L1w7SEvtGgvgGE2zKYIks/CRYYm0Wuzo/r15KBAb/XSE7ILq9ADmIetJm89kWRg==}
|
||||
peerDependencies:
|
||||
@ -4890,8 +4878,8 @@ packages:
|
||||
undici-types@6.20.0:
|
||||
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
||||
|
||||
unhead@1.11.18:
|
||||
resolution: {integrity: sha512-TWgGUoZMpYe2yJwY6jZ0/9kpQT18ygr2h5lI6cUXdfD9UzDc0ytM9jGaleSYkj9guJWXkk7izYBnzJvxl8mRvQ==}
|
||||
unhead@2.0.2:
|
||||
resolution: {integrity: sha512-1pcK/rSA70sezpdgmupQPd/yrul8pVFJRwMvWjEthbsXoTXMqjNQlV7NBXWeWt5r2uje1lZJsvRTHF7IvdOhcg==}
|
||||
|
||||
unicorn-magic@0.1.0:
|
||||
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
|
||||
@ -5400,9 +5388,6 @@ packages:
|
||||
resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
zhead@2.2.4:
|
||||
resolution: {integrity: sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag==}
|
||||
|
||||
zip-stream@6.0.1:
|
||||
resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==}
|
||||
engines: {node: '>= 14'}
|
||||
@ -6579,27 +6564,10 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.24.0
|
||||
eslint-visitor-keys: 4.2.0
|
||||
|
||||
'@unhead/dom@1.11.18':
|
||||
dependencies:
|
||||
'@unhead/schema': 1.11.18
|
||||
'@unhead/shared': 1.11.18
|
||||
|
||||
'@unhead/schema@1.11.18':
|
||||
'@unhead/vue@2.0.2(vue@3.5.13(typescript@5.8.2))':
|
||||
dependencies:
|
||||
hookable: 5.5.3
|
||||
zhead: 2.2.4
|
||||
|
||||
'@unhead/shared@1.11.18':
|
||||
dependencies:
|
||||
'@unhead/schema': 1.11.18
|
||||
packrup: 0.1.2
|
||||
|
||||
'@unhead/vue@1.11.18(vue@3.5.13(typescript@5.8.2))':
|
||||
dependencies:
|
||||
'@unhead/schema': 1.11.18
|
||||
'@unhead/shared': 1.11.18
|
||||
hookable: 5.5.3
|
||||
unhead: 1.11.18
|
||||
unhead: 2.0.2
|
||||
vue: 3.5.13(typescript@5.8.2)
|
||||
|
||||
'@unocss/astro@66.0.0(vite@6.1.0(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass-embedded@1.83.4)(terser@5.38.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
|
||||
@ -9330,8 +9298,6 @@ snapshots:
|
||||
|
||||
package-manager-detector@0.2.8: {}
|
||||
|
||||
packrup@0.1.2: {}
|
||||
|
||||
page-stack-vue3@2.5.6(vue-router@4.5.0(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2)):
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.8.2)
|
||||
@ -10278,11 +10244,8 @@ snapshots:
|
||||
|
||||
undici-types@6.20.0: {}
|
||||
|
||||
unhead@1.11.18:
|
||||
unhead@2.0.2:
|
||||
dependencies:
|
||||
'@unhead/dom': 1.11.18
|
||||
'@unhead/schema': 1.11.18
|
||||
'@unhead/shared': 1.11.18
|
||||
hookable: 5.5.3
|
||||
|
||||
unicorn-magic@0.1.0: {}
|
||||
@ -10872,8 +10835,6 @@ snapshots:
|
||||
|
||||
yoctocolors@2.1.1: {}
|
||||
|
||||
zhead@2.2.4: {}
|
||||
|
||||
zip-stream@6.0.1:
|
||||
dependencies:
|
||||
archiver-utils: 5.0.2
|
||||
|
@ -3,18 +3,21 @@ const VITE_BUILD_COMMIT = import.meta.env.VITE_BUILD_COMMIT;
|
||||
import { routes } from 'vue-router/auto-routes';
|
||||
|
||||
definePage({ meta: { title: '首页' } });
|
||||
import { useHead, useSeoMeta } from '@unhead/vue';
|
||||
|
||||
useHead({
|
||||
// Classes
|
||||
bodyAttrs: { class: { overflow: true } },
|
||||
// Template params
|
||||
templateParams: { separator: '|', siteName: 'My App' },
|
||||
// Titles
|
||||
title: 'Hello World',
|
||||
titleTemplate: '%s %separator %siteName',
|
||||
titleTemplate: (title) => `${title} | My App`,
|
||||
// Deduping
|
||||
// script: [{ key: '123', src: '/script.js' }],
|
||||
});
|
||||
|
||||
useSeoMeta({
|
||||
description: '首页',
|
||||
title: 'Hello World',
|
||||
});
|
||||
|
||||
consola.info('routes', routes);
|
||||
|
||||
const FComponent: import('vue').FunctionalComponent<{ prop: string }> = (props /* context */) => (
|
||||
|
Reference in New Issue
Block a user