fix(nuxt): don't try to override computed layouts in definePageMeta (#9161)

This commit is contained in:
Mohammad Saleh Fadaei 2023-01-14 04:28:54 +03:30 committed by GitHub
parent f4ba7ec82d
commit 5b19a0dc34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 6 deletions

View File

@ -1,4 +1,4 @@
import { reactive, h } from 'vue'
import { reactive, h, isReadonly } from 'vue'
import { parseURL, stringifyParsedURL, parseQuery, stringifyQuery, withoutBase, isEqual, joinURL } from 'ufo'
import { createError } from 'h3'
import { defineNuxtPlugin, clearError, navigateTo, showError, useRuntimeConfig, useState } from '..'
@ -222,8 +222,8 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>((nuxtApp) => {
nuxtApp.hooks.hookOnce('app:created', async () => {
router.beforeEach(async (to, from) => {
to.meta = reactive(to.meta || {})
if (nuxtApp.isHydrating) {
to.meta.layout = initialLayout.value ?? to.meta.layout
if (nuxtApp.isHydrating && initialLayout.value && !isReadonly(to.meta.layout)) {
to.meta.layout = initialLayout.value
}
nuxtApp._processingMiddleware = true

View File

@ -1,4 +1,4 @@
import { computed, reactive, shallowRef } from 'vue'
import { computed, isReadonly, reactive, shallowRef } from 'vue'
import type {
NavigationGuard,
RouteLocation
@ -119,8 +119,8 @@ export default defineNuxtPlugin(async (nuxtApp) => {
const initialLayout = useState('_layout')
router.beforeEach(async (to, from) => {
to.meta = reactive(to.meta)
if (nuxtApp.isHydrating) {
to.meta.layout = initialLayout.value ?? to.meta.layout
if (nuxtApp.isHydrating && initialLayout.value && !isReadonly(to.meta.layout)) {
to.meta.layout = initialLayout.value
}
nuxtApp._processingMiddleware = true

View File

@ -410,6 +410,16 @@ describe('layouts', () => {
expect(html).toContain('Custom Layout:')
await expectNoClientErrors('/with-dynamic-layout')
})
it('should work with a computed layout', async () => {
const html = await $fetch('/with-computed-layout')
// Snapshot
// expect(html).toMatchInlineSnapshot()
expect(html).toContain('with-computed-layout')
expect(html).toContain('Custom Layout')
await expectNoClientErrors('/with-computed-layout')
})
it('should allow passing custom props to a layout', async () => {
const html = await $fetch('/layouts/with-props')
expect(html).toContain('some prop was passed')

View File

@ -0,0 +1,11 @@
<script setup>
definePageMeta({
layout: computed(() => 'custom')
})
</script>
<template>
<div>
<div>with-computed-layout.vue</div>
</div>
</template>