Nuxt 入门实战 - 05:特性
自动导入
说明:以下目录只要有引用,都具有自动导入能力
- components:可以被template 直接使用
- composables:其中的导出,可以直接被template、ts、js 文件直接引用使用
- utils:其中的导出,可以直接被template、ts、js 文件直接引用使用
拉取数据
<script setup>
const { data } = await useFetch('/api/hello')
</script><template><div><p>Result of <code>/api/hello</code>:</p><pre>{{ data }}</pre><p><NuxtLink to="/external">Visit /external</NuxtLink></p><p><NuxtLink to="/component">Visit /component</NuxtLink></p></div>
</template>
状态共享
说明:此时counter 和 sameCounter 就共用一个状态了
//app.vue
<script setup>
//1.赋值
const counter = useState("counter", () => 30);
//2.获取共享状态
const sameCounter = useState("counter");
</script><template><div><p>Counter: {{ counter }}</p><p><button @click="counter--">-</button><button @click="counter++">+</button></p><p>Same Counter: {{ sameCounter }}</p><Test></Test></div>
</template>
Meta Tags
说明:可以在页面template中添加html head 内容,修改页面head数据
<template><div><p>We are using renderless <code><Html></code>,<code><Meta></code>, <code><Title></code> components<br />that can magically bind the meta inside Vue components.</p><Html lang="en"><Head><Title>Lucky number: {{ number }}</Title><Meta name="description" :content="`My page's ${number} description`" /></Head></Html><p><button @click="number = Math.round(Math.random() * 100)">Click me and see the title updates</button></p><p><NuxtLink to="/about">About page</NuxtLink></p></div> </template>
Layout
-
NuxtLayout 默认引用Layouts/default.vue 布局
-
NuxtLink 相当于router-link
-
动态修改layout
setPageLayout(layoutname)
-
导航进特定路由前,执行中间件
//pages/other.vue <script setup> definePageMeta({middleware: 'other' }) </script>
进入other路由器,会先执行middleware/other.ts 中间件
//middleware/other.ts export default defineNuxtRouteMiddleware(() => {setPageLayout('other') })
routing
-
禁止跳转进某个路由
//pages/fobidden.vue <template><div>Forbidden</div> </template><script setup> definePageMeta({middleware: () => {console.log("Strictly forbidden.");//! 返回false,可禁止跳入此路由return false;}, }); </script>
-
利用middleware 重定向
//pages/redirect.vue <template><div>You should never see this page</div> </template><script setup>definePageMeta({middleware: 'redirect-me' }) </script>
//middleware/redirect-me.ts export default defineNuxtRouteMiddleware((to) => {const { $config } = useNuxtApp()if ($config) {console.log('Accessed runtime config within middleware.')}console.log('Heading to', to.path, 'but I think we should go somewhere else...')return '/secret' })
-
全局中间件:只要切换路由就会执行
//middleware.global.ts export default defineNuxtRouteMiddleware(() => {console.log('running global middleware') })
-
获取当前路由信息
const route = useRoute()
-
路由占位符传参
//app.vue <button class="n-link-base" @click="$router.push(`/parent/reload-${(Math.random() * 100).toFixed()}`)">Keyed child </button>
说明:会先加载parent组件,然后通过parent再嵌套载入reload-[id].vue 组件,会将reload-后面的参数动态传给reload-[id].vue 组件
NuxtLink 相当于 router-link,NuxtPage 相当于 router-view
配置extend
-
nuxt.config.ts 继承
//nuxt.config.ts export default defineNuxtConfig({extends: ['./ui','./base'],runtimeConfig: {public: {theme: {primaryColor: 'user_primary'}}},modules: ['@nuxt/ui'] })
app.config.ts 也会自动继承
export default defineAppConfig({foo: 'user',bar: 'user',baz: 'base',array: ['user','user','user'] })
-
base 配置
//base/nuxt.config.ts export default defineNuxtConfig({imports: {dirs: ['utils']},runtimeConfig: {public: {theme: {primaryColor: 'base_primary',secondaryColor: 'base_secondary'}}} })
export default defineAppConfig({bar: 'base',baz: 'base',array: () => ['base','base','base'],arrayNested: {nested: {array: ['base','base','base']}} })
最终nuxt.config.ts 和app.config.ts 都会对应合并
错误处理
-
通过插件捕获错误
//plugins/error.ts export default defineNuxtPlugin((nuxtApp) => {nuxtApp.hook('vue:error', (..._args) => {console.log('vue:error')// if (process.client) {// console.log(..._args)// }})nuxtApp.hook('app:error', (..._args) => {console.log('app:error')// if (process.client) {// console.log(..._args)// }})//全局错误处理nuxtApp.vueApp.config.errorHandler = (..._args) => {console.log('global error handler')// if (process.client) {// console.log(..._args)// }} })
-
中间件处理错误
//middleware/error.global.ts export default defineNuxtRouteMiddleware((to) => {if ('middleware' in to.query) {return showError('error in middleware')} })
说明:根目录创建error.vue,出错就会跳转至此页面,错误消息通过defindPros 中的error.message拿到
module
可以将页面拓展到模块,然后extendPages接口将拓展的页面加进路由中
-
配置nuxt.config.ts 添加对应模块
//nuxt.config.js export default defineNuxtConfig({modules: ['~/modules/pages/index','@nuxt/ui'] })
-
setup添加模块页面
//modules/pages/index.ts import { defineNuxtModule, extendPages } from '@nuxt/kit' import { resolve } from 'pathe'export default defineNuxtModule({setup () {extendPages((pages) => {// Add /test pagepages.push({name: 'Test',path: '/test',file: resolve(__dirname, './pages/test.vue')})})} })
Cookie
//默认为空,具备响应式
const user = useCookie<{ name: string }>('user')
const logins = useCookie<number>('logins')
更多
最近我开源了一个文章助手artipub,可以帮你一键将markdown发布至多平台,方便大家更好的传播知识和分享你的经验。
官网地址:https://artipub.github.io/artipub/ (提示:国内访问可能有点慢,翻墙就会很快)
帮忙点个star⭐,让更多人知道这个工具,谢谢大家🙏。如果你有兴趣,欢迎加入你的加入,一起完善这个工具。
参考文献
- https://nuxt.com/docs/examples/features/auto-imports
- https://nuxt.com/docs/examples/features/data-fetching
- https://nuxt.com/docs/examples/features/state-management
- https://nuxt.com/docs/examples/features/meta-tags
- https://nuxt.com/docs/examples/features/layouts
- https://nuxt.com/docs/examples/routing/middleware
- https://nuxt.com/docs/examples/routing/pages
- https://nuxt.com/docs/examples/advanced/config-extends
- https://nuxt.com/docs/examples/advanced/error-handling