mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
feat(nuxt): add open
option in navigateTo
helper (#21333)
This commit is contained in:
parent
05f3decfa9
commit
c4e5ac83bf
@ -18,6 +18,7 @@ interface NavigateToOptions {
|
|||||||
replace?: boolean
|
replace?: boolean
|
||||||
redirectCode?: number
|
redirectCode?: number
|
||||||
external?: boolean
|
external?: boolean
|
||||||
|
open?: OpenOptions
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -69,6 +70,58 @@ An object accepting the following properties:
|
|||||||
|
|
||||||
Allows navigating to an external URL when set to `true`. Otherwise, `navigateTo` will throw an error, as external navigation is not allowed by default.
|
Allows navigating to an external URL when set to `true`. Otherwise, `navigateTo` will throw an error, as external navigation is not allowed by default.
|
||||||
|
|
||||||
|
- `open` (optional)
|
||||||
|
|
||||||
|
**Type**: `OpenOptions`
|
||||||
|
|
||||||
|
Allows navigating to the URL using the [open()](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) method of the window. This option is only applicable on the client side and will be ignored on the server side.
|
||||||
|
|
||||||
|
An object accepting the following properties:
|
||||||
|
|
||||||
|
- `target`
|
||||||
|
|
||||||
|
**Type**: `string`
|
||||||
|
|
||||||
|
**Default**: `'_blank'`
|
||||||
|
|
||||||
|
A string, without whitespace, specifying the name of the browsing context the resource is being loaded into.
|
||||||
|
|
||||||
|
- `windowFeatures` (optional)
|
||||||
|
|
||||||
|
**Type**: `OpenWindowFeatures`
|
||||||
|
|
||||||
|
An object accepting the following properties:
|
||||||
|
|
||||||
|
- `popup` (optional)
|
||||||
|
|
||||||
|
**Type**: `boolean`
|
||||||
|
|
||||||
|
- `width` or `innerWidth` (optional)
|
||||||
|
|
||||||
|
**Type**: `number`
|
||||||
|
|
||||||
|
- `height` or `innerHeight` (optional)
|
||||||
|
|
||||||
|
**Type**: `number`
|
||||||
|
|
||||||
|
- `left` or `screenX` (optional)
|
||||||
|
|
||||||
|
**Type**: `number`
|
||||||
|
|
||||||
|
- `top` or `screenY` (optional)
|
||||||
|
|
||||||
|
**Type**: `number`
|
||||||
|
|
||||||
|
- `noopener` (optional)
|
||||||
|
|
||||||
|
**Type**: `boolean`
|
||||||
|
|
||||||
|
- `noreferrer` (optional)
|
||||||
|
|
||||||
|
**Type**: `boolean`
|
||||||
|
|
||||||
|
Refer to the [documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) for more detailed information on the **windowFeatures** properties.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Navigating Within a Vue Component
|
### Navigating Within a Vue Component
|
||||||
@ -120,3 +173,20 @@ await navigateTo('https://nuxt.com', {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Navigating using open()
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
// will open 'https://nuxt.com' in a new tab
|
||||||
|
await navigateTo('https://nuxt.com', {
|
||||||
|
open: {
|
||||||
|
target: '_blank',
|
||||||
|
windowFeatures: {
|
||||||
|
width: 500,
|
||||||
|
height: 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
@ -83,10 +83,29 @@ const isProcessingMiddleware = () => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conditional types, either one or other
|
||||||
|
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
|
||||||
|
type XOR<T, U> = (T | U) extends Object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U
|
||||||
|
|
||||||
|
export type OpenWindowFeatures = {
|
||||||
|
popup?: boolean
|
||||||
|
noopener?: boolean
|
||||||
|
noreferrer?: boolean
|
||||||
|
} & XOR<{width?: number}, {innerWidth?: number}>
|
||||||
|
& XOR<{height?: number}, {innerHeight?: number}>
|
||||||
|
& XOR<{left?: number}, {screenX?: number}>
|
||||||
|
& XOR<{top?: number}, {screenY?: number}>
|
||||||
|
|
||||||
|
export type OpenOptions = {
|
||||||
|
target: '_blank' | '_parent' | '_self' | '_top' | (string & {})
|
||||||
|
windowFeatures?: OpenWindowFeatures
|
||||||
|
}
|
||||||
|
|
||||||
export interface NavigateToOptions {
|
export interface NavigateToOptions {
|
||||||
replace?: boolean
|
replace?: boolean
|
||||||
redirectCode?: number,
|
redirectCode?: number
|
||||||
external?: boolean
|
external?: boolean
|
||||||
|
open?: OpenOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: NavigateToOptions): Promise<void | NavigationFailure | false> | false | void | RouteLocationRaw => {
|
export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: NavigateToOptions): Promise<void | NavigationFailure | false> | false | void | RouteLocationRaw => {
|
||||||
@ -95,6 +114,23 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
|
|||||||
}
|
}
|
||||||
|
|
||||||
const toPath = typeof to === 'string' ? to : ((to as RouteLocationPathRaw).path || '/')
|
const toPath = typeof to === 'string' ? to : ((to as RouteLocationPathRaw).path || '/')
|
||||||
|
|
||||||
|
// Early open handler
|
||||||
|
if (options?.open) {
|
||||||
|
if (process.client) {
|
||||||
|
const { target = '_blank', windowFeatures = {} } = options.open
|
||||||
|
|
||||||
|
const features = Object.entries(windowFeatures)
|
||||||
|
.filter(([_, value]) => value !== undefined)
|
||||||
|
.map(([feature, value]) => `${feature.toLowerCase()}=${value}`)
|
||||||
|
.join(', ')
|
||||||
|
|
||||||
|
open(toPath, target, features)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
const isExternal = options?.external || hasProtocol(toPath, { acceptRelative: true })
|
const isExternal = options?.external || hasProtocol(toPath, { acceptRelative: true })
|
||||||
if (isExternal && !options?.external) {
|
if (isExternal && !options?.external) {
|
||||||
throw new Error('Navigating to external URL is not allowed by default. Use `navigateTo (url, { external: true })`.')
|
throw new Error('Navigating to external URL is not allowed by default. Use `navigateTo (url, { external: true })`.')
|
||||||
|
@ -34,7 +34,7 @@ describe.skipIf(isWindows || process.env.TEST_BUILDER === 'webpack' || process.e
|
|||||||
|
|
||||||
it('default client bundle size', async () => {
|
it('default client bundle size', async () => {
|
||||||
stats.client = await analyzeSizes('**/*.js', publicDir)
|
stats.client = await analyzeSizes('**/*.js', publicDir)
|
||||||
expect(roundToKilobytes(stats.client.totalBytes)).toMatchInlineSnapshot('"98.3k"')
|
expect(roundToKilobytes(stats.client.totalBytes)).toMatchInlineSnapshot('"98.5k"')
|
||||||
expect(stats.client.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(`
|
expect(stats.client.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
"_nuxt/entry.js",
|
"_nuxt/entry.js",
|
||||||
@ -45,7 +45,7 @@ describe.skipIf(isWindows || process.env.TEST_BUILDER === 'webpack' || process.e
|
|||||||
|
|
||||||
it('default server bundle size', async () => {
|
it('default server bundle size', async () => {
|
||||||
stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||||
expect(roundToKilobytes(stats.server.totalBytes)).toMatchInlineSnapshot('"62.7k"')
|
expect(roundToKilobytes(stats.server.totalBytes)).toMatchInlineSnapshot('"62.8k"')
|
||||||
|
|
||||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||||
expect(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2286k"')
|
expect(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2286k"')
|
||||||
|
Loading…
Reference in New Issue
Block a user