布局
布局是围绕包含多个页面的公共用户界面的页面的包装器,例如页眉和页脚显示。
布局是使用slot 组件显示页面内容的Vue文件。
默认情况下使用layouts/default.vue文件。
自定义布局可以设置为页面元数据的一部分。
- 方式一:默认布局
- 在layouts目录下新建默认的布局组件,比如:layouts/default.vue
- 然后在app.vue中通过内置组件来使用
layouts/default.vue
<template>
<div class="layout">
<div class="header">
<div>我是Header</div>
</div>
<!-- 页面的内容 -->
<slot></slot>
<div class="footer">我是footer</div>
</div>
</template>
app.vue
<template>
<!-- 布局 -->
<NuxtLayout>
<!-- 页面 -->
<NuxtPage></NuxtPage>
</NuxtLayout>
</template>
- 方式二:自定义布局(Custom Layout)
- 继续在layouts文件夹下新建 Layout 布局组件,比如: layouts/custom-layout.vue
- 然后在app.vue中给内置组件 指定name属性 的值为:custom-layout
- 也支持在页面中使用 definePageMeta 宏函数来指定 layout 布局
<template>
<!-- 布局 -->
<NuxtLayout :name="name">
<!-- 页面 -->
<NuxtPage></NuxtPage>
</NuxtLayout>
</template>
<script setup>
// 默认是default
// const name = "default";
// 使用自定义布局(修改这个name是全局所有页面都修改了)
const name = "custom-layout";
</script>
对单个页面进行自定义布局,比如login并不需要页眉与页脚
login.vue
<template>
<div>Page: login</div>
</template>
<script lang="ts" setup>
// 该页面重新定义使用的 layout
definePageMeta({
layout: "custom-layout",
});
</script>
<style scoped></style>
删除线格式 当然你可以动态设置布局,也可以在布局基础上修改布局。
链接: link
渲染模式
浏览器 和 服务器都可以解释 JavaScript 代码,都可以将 Vue.js 组件呈现为 HTML 元素。此过程称为渲染。
- 在客户端将 Vue.js 组件呈现为 HTML 元素,称为:客户端渲染模式
- 在服务器将 Vue.js 组件呈现为 HTML 元素,称为:服务器渲染模式
而Nuxt3是支持多种渲染模式,比如:
- 客户端渲染模式(CSR): 只需将 ssr 设置为 false
- 服务器端渲染模式(SSR):只需将 ssr 设置为 true
- 混合渲染模式(SSR | CSR | SSG | SWR):需在 routeRules 根据每个路由动态配置渲染模式(beta版本)
nuxt.config.ts
export default defineNuxtConfig({
// ssr: false, // ssr为true就是服务端渲染,false就是客户端渲染
// 混合渲染(不同路由设置不同渲染模式)
routeRules: {
"/": { ssr: true }, // ssr
"/category": { ssr: false }, // spa 应用
// 3.0.0-12rc -> NetLify
"/cart": { static: true }, // 只会在构建时生成一次静态页面
"/profile": { swr: true }, // 只会生成多次静态页面( 会自动重新验证页面时候需要重新生成 )
},
});
插件plugin
Nuxt3支持自定义插件进行扩展,创建插件有两种方式:
- 方式一:直接使用 useNuxtApp() 中的 provide(name, vlaue) 方法直接创建,比如:可在App.vue中创建
- useNuxtApp 提供了访问 Nuxt 共享运行时上下文的方法和属性(两端可用):provide、hooks、callhook、vueApp等
- 使用provide函数创建Nuxt插件,使值和帮助方法在你的Nuxt应用程序中跨所有组合和组件可用。
- 方式二:在 plugins 目录中创建插件(推荐)
- 顶级和子目录index文件写的插件会在创建Vue应用程序时会自动加载和注册
- .server 或 .client 后缀名插件,可区分服务器端或客户端,用时需区分环境
- 插件注册顺序可以通过在文件名前加上一个数字来控制插件注册的顺序(此插件依赖另一个插件需要注意顺序)
- 如果一个可组合文件依赖于Vue.js的生命周期,它将无法工作 。通常情况下,Vue.js组合组件被绑定到当前组件实例,而插件只被绑定到nuxtApp实例
方式一
const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)
// Prints "Hello name!"
console.log(nuxtApp.$hello('name'))
// $hello 已经成为nuxtApp上下文的新和自定义部分,它在nuxtApp可访问的所有地方都可用。
方式二
plugins
| - myPlugin.ts
| - myOtherPlugin
| --- supportingFile.ts
| --- index.ts
| - 1.myPlugin.ts
| - 2.myOtherPlugin.ts
| - myPlugin.client.ts
| - myOtherPlugin.server.ts
supportingFile.ts不会被注册 按顺序注册 以及只在server端或者client生效
export default defineNuxtPlugin((nuxtApp) => {
// 传递给插件的唯一参数是 nuxtApp.
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`
}
}
})
<template>
<div>
{{ $hello('world') }}
</div>
</template>
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>
生命周期 lifecycle hooks
App Hooks 主要可由 Nuxt 插件 使用 hooks 来监听 生命周期,也可用于 Vue 组合 API 。
但是,如在组件中编写hooks来监听,那 create和setup hooks就监听不了,因为这些hooks已经触发完了监听。
- 在plugin文件中插件中使用hook监听
// plugin/lifecycle.ts文件中
export default defineNuxtPlugin((nuxtApp) => {
// 监听App的生命周期
// Server & Client
nuxtApp.hook("app:created", (vueApp) => {
console.log("app:created");
});
// Client
nuxtApp.hook("app:beforeMount", (vueApp) => {
console.log("app:beforeMount");
});
// Server & Client
nuxtApp.hook("vue:setup", () => {
console.log("vue:setup");
});
// Server
nuxtApp.hook("app:rendered", (renderContext) => {
console.log("app:rendered");
});
// Client
nuxtApp.hook("app:mounted", (vueApp) => {
console.log("app:mounted");
});
});
- 在app.vue中使用hook监听
<template>
<div>
<NuxtPage></NuxtPage>
</div>
</template>
<script setup>
const nuxtApp = useNuxtApp();
// Server & Client
// 监听不到此函数,因为在setup里
nuxtApp.hook("app:created", (vueApp) => {
// console.log("app:created");
});
// Client
// 监听不到此函数,因为在setup里
nuxtApp.hook("app:beforeMount", (vueApp) => {
// console.log("app:beforeMount");
});
// Server & Client
// 监听不到此函数,因为在setup里
nuxtApp.hook("vue:setup", () => {
// console.log("vue:setup");
});
// Server
nuxtApp.hook("app:rendered", (renderContext) => {
// console.log("app:rendered");
});
// Client
nuxtApp.hook("app:mounted", (vueApp) => {
// console.log("app:mounted");
});
</script>
我们只能监听到app:mounted,因为我们是写在setup里的
- 使用vue原来的组合api监听
<template>
<div class="home">home</div>
</template>
<script>
export default {
setup() {
console.log("setup");
return {};
},
beforeCreate() {
console.log("beforeCreate");
},
created() {
console.log("created");
},
beforeMount() {
console.log("beforeMount");
},
mounted() {
console.log("mounted");
},
beforeUnmount() {
console.log("beforeUnmount");
},
unmounted() {
console.log("unmounted");
},
};
</script>
server打印 setup beforeCreate created
<template>
<div class="home">home</div>
</template>
<script setup>
console.log("setup");
onBeforeMount(() => {
console.log("onBeforeMount");
});
onMounted(() => {
console.log("onMounted");
});
</script>
serve只打印setup
使用vue组件生命周期,需要注意服务端只会回调 beforeCreate created两个函数,如果是setup中,则都不会回调