nuxt3.10 跑马观花

340 阅读6分钟

资料网站

Nuxt Modules

What Is Nuxt SEO? · Nuxt SEO

Nuxt: The Intuitive Vue Framework · Nuxt

Nuxt 中文站 - 直观的Web框架 Nuxt3文档 · Nuxt

追加补充

访问浏览器相关的对象

// 判断是否浏览器环境
if (process.browser) {
  window.addEventListener("scroll", (e: Event) => {
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    if (scrollTop >= 200) {
      hideTopNav.value = true;
    } else {
      hideTopNav.value = false;
    }
  });
}

创建项目

优先按照官网文档的方式创建: Installation · Get Started with Nuxt

pnpm dlx nuxi@latest init <project-name>

如果创建报错,请参考这篇文章解决: 使用nuxi创建nuxt3项目报错 - 掘金 (juejin.cn)

默认的路径别名

~: 这个是nuxt3中默认的路径别名,表示项目根目录。

你要引入资源可以这样

import { fun } fomr '~/utils/test.ts'

配置文件

nuxt.config.ts

nuxt.config.ts

app.config.ts

Configuration · Get Started with Nuxt

页面与普通组件与布局组件

视图和组件都是自动引入的

Views · Get Started with Nuxt

app.vue

是界面的入口点

你不使用路由时

<template>
  <div>
   <h1>Welcome to the homepage</h1>
  </div>
</template>

你使用路由,不使用布局组件时

<template>
  <!-- 路由会渲染到这个地方 -->
  <NuxtPage />
</template>

你既使用路由,又使用布局组件时

<template>
  <!-- 这里会应用默认布局。即: 项目根目录/layouts/default.vue 这个文件 -->
  <NuxtLayout>
     <!-- 路由会渲染到这个地方 -->
    <NuxtPage />
  </NuxtLayout>
</template>

页面

  • 页面必须放在项目根目录/pages

普通组件

  • 普通组件必须放在项目根目录/components

布局组件

layouts/ · Nuxt Directory Structure

  • 布局组件必须放在项目根目录/layouts

使用默认布局组件

如果你仅有一个默认布局,那么直接将布局组件文件名,命名为:default.vue

项目根目录/layouts/default.vue

<template>
  <div>
    <AppHeader />
    <!-- 这里的slot与vue中的默认slot用法一致 -->
    <slot />
    <AppFooter />
  </div>
</template>

app.vue

<template>
  <!-- 这里会应用默认布局。即: 项目根目录/layouts/default.vue 这个文件 -->
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

使用其他布局组件

项目根目录/layouts/other.vue 这是一个其他布局组件

在app.vue使用其他布局组件

app.vue

<script setup lang="ts">
// You might choose this based on an API call or logged-in status
const layout = "other";
</script>
<template>
  <!-- 这里会应用默认布局。即: 项目根目录/layouts/other.vue 这个文件 -->
  <NuxtLayout :name="layout">
    <NuxtPage />
  </NuxtLayout>
</template>
在其他页面使用其他布局组件
<script setup lang="ts">
definePageMeta({
  // 这里layout默认为true,表示如果存在上级布局组件,当前页面是否需要包含在上级路由组件中。
  layout: false,
})
</script>

<template>
  <div>
    <NuxtLayout name="custom">
      <template #header> Some header template content. </template>

      The rest of the page
    </NuxtLayout>
  </div>
</template>

使用静态资源

存放位置与访问方式

  • 项目根目录/public

在vue文件中访问 public目录 资源

假设存在资源: 项目根目录/public/img/nuxt.png

<template>
  <img src="/img/nuxt.png" alt="Discover Nuxt 3" />
</template>
  • 项目根目录/assets

假设存在资源: 项目根目录/public/assets/nuxt.png

在vue文件中访问 assets目录 资源

<template>
  <img src="~/assets/img/nuxt.png" alt="Discover Nuxt 3" />
</template>

样式, scss与字体文件

如需使用scss/sass 或 less 或 Stylus, 需要先安装对应插件

pnpm install sass

pnpm install less

pnpm install stylus

配置scss全局变量

nuxt.config.ts

export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "~/assets/_colors.scss" as *;'
        }
      }
    }
  }
})

全局样式

nuxt.config.ts

export default defineNuxtConfig({
  css: ['~/assets/css/main.css', '~/assets/scss/comm.scss']
})

nuxt.config.ts

export default defineNuxtConfig({
  app: {
    head: {
      link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
    }
}})

任意vue组件

useHead({
  link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
})

通过自定义Nitro插件引入

项目根目录/server/plugins/my-plugin.ts

export default defineNitroPlugin((nitro) => {
  nitro.hooks.hook('render:html', (html) => {
    html.head.push('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">')
  })
})

某个vue组件单独引入样式(虽然是单独引入,但这些样式的效果对全局生效)

<script>
// Use a static import for server-side compatibility
import '~/assets/css/first.css'

// Caution: Dynamic imports are not server-side compatible
import('~/assets/css/first.css')
</script>

<style>
@import url("~/assets/css/second.css");
</style>
<style lang="scss">
@use "~/assets/scss/main.scss";
</style>

局部样式

<template>
  <div class="example">hi</div>
</template>

<style scoped>
.example {
  color: red;
}
</style>

css变量

<script setup lang="ts">
const color = ref("red")
</script>

<template>
  <div class="text">hello</div>
</template>

<style scoped>
.text {
  color: v-bind(color);
}
</style>

字体文件

字体文件也应该放在项目根目录/public

假设有字体文件项目根目录/public/font/FarAwayGalaxy.woff

在css文件中引入字体文件

@font-face {
  font-family: 'FarAwayGalaxy';
  src: url('/fonts/FarAwayGalaxy.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

使用指定字体

<style>
h1 {
  font-family: 'FarAwayGalaxy', sans-serif;
}
</style>

路由管理

Routing · Get Started with Nuxt

  • 路由中间件必须全部放在项目根目录/routes目录
  • 路由组件必须全放在项目根目录/pages目录
  • nuxt2不同的是, nuxt3不会在.nuxt目录生成静态路由配置文件
  • 默认的路由名是文件名test.vue的路由名是test, hello/index.vue的路由名是hello,hello/demo.vue的路由名是hello-demo

开发环境,可以通过nuxt devtool查看所有路由path,以及对应路由名, 和对应路由使用的中间件,以及该路由使用的布局组件

image.png

| pages/
---| about.vue
---| index.vue
---| posts/
-----| [id].vue

路由导航

<template>
  <header>
    <nav>
      <ul>
        <li><NuxtLink to="/about">About</NuxtLink></li>
        <li><NuxtLink to="/posts/1">Post 1</NuxtLink></li>
        <li><NuxtLink to="/posts/2">Post 2</NuxtLink></li>
      </ul>
    </nav>
  </header>
</template>
const $router = useRouter();
function onClick() {
  $router.push({ path: "/" });
}

获取路由参数

<script setup lang="ts">
const route = useRoute()

// When accessing /posts/1, route.params.id will be 1
console.log(route.params.id)
    
// 获取所有查询参数对象
const query = route.query;

// 或者直接获取某个特定查询参数
const exampleParam = route.query.example;
</script>

多级路由参数

多级路由参数可以通过创建嵌套的文件夹结构来实现。例如,假设你有一个产品目录系统,需要根据类别、品牌和产品ID访问不同产品详情页面,你可以按照以下方式设置多级动态路由:

- pages/ 
|-- product/ 
|-----| _category/ # 动态一级参数:类别 - 
|-----|-----| _brand/ # 动态二级参数:品牌 - 
|-----|-----|----| _id.vue # 动态三级参数:产品ID
export default {
    setup() {
      const route = useRoute();
  
      // 获取路由参数
      const category = route.params.category; // "categoryA"
      const brand = route.params.brand;       // "brandB"
      const id = route.params.id;            // "product123"
  
      // ...
    }
  };

路由中间件

定义路由中间件

function isAuthenticated(): boolean { return false }
// ---cut---
export default defineNuxtRouteMiddleware((to, from) => {
  // isAuthenticated() is an example method verifying if a user is authenticated
  if (isAuthenticated() === false) {
    return navigateTo('/login')
  }
})

在页面中使用路由中间件

<script setup lang="ts">
definePageMeta({
  middleware: 'auth'
})
</script>

<template>
  <h1>Welcome to your dashboard</h1>
</template>

嵌套路由

使用<NuxtChild> 组件用于在父级路由组件中渲染嵌套路由对应的子组件

嵌套路由结构

image.png

嵌套路由结构说明

父路由组件可以叫任意名称,子路由组件,必须放在和父路由组件同层级的同名文件夹下,这时nuxt3就会给你生成嵌套路由。

上面例子parent.vue是父路由组件,parent文件夹用于存放子路由。

parent.vue要能渲染子路由需要这么做:

<template>
  <!-- 子页面的出口 -->
  <NuxtChild />
</template>

状态管理

State Management · Get Started with Nuxt

Pinia · Nuxt Modules

注意: ts的定义是自动默认引入的无需手动引入,如果出现找不到名称“defineStore”这种ts类型错误,那重新启动一次本地nuxt服务,等待imports.d.ts生成相关的全局类型定义

image.png

那么你的store定义大概是这样的

image.png

使用定义的store大概是这样的

image.png

使用pina进行状态管理

pnpm add @pinia/nuxt

nuxt.config.ts

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  // 引入`@pinia/nuxt`
  modules: ["@pinia/nuxt"],
  // 指定pinia的store存放目录
  pinia: {
    storesDirs: ["./stores/**"],
  },
  $production: {
    routeRules: {
      "/**": { isr: true },
    },
  },
});

nuxt3中使用pinia无需像vite + vue3项目中在某个地方进行初始化,直接在vue组件中使用即可

nuxt3中使用pinia无需像vite + vue3项目中在某个地方进行初始化,直接在vue组件中使用即可

数据获取

Data fetching · Get Started with Nuxt

错误处理

Error Handling · Get Started with Nuxt

浏览器兼容性

关于Nuxt3.6兼容低版本游览器的实战以及可能存在的问题_nuxt-vite-legacy-CSDN博客

部署发布

Deployment · Get Started with Nuxt

使用第三方模块

nuxt3官方收录模块

Nuxt Modules

animate.css

pnpm add animate.css

可以直接在app.vue中引入,或某个具体页面中引入

<script>
import 'animate.css'
</script>

<style>
@import url("animate.css");
</style>

也可以在nuxt.config.ts中作为全局资源引入

export default defineNuxtConfig({
  css: ['animate.css']
})

tailwind css

Config - Nuxt Tailwind (nuxtjs.org)

pnpm install -D @nuxtjs/tailwindcss

nuxt.config.ts

export default defineNuxtConfig({
  modules: ['@nuxtjs/tailwindcss']
})

创建tailwind css配置文件

npx tailwindcss init
import type { Config } from 'tailwindcss'
import colors from 'tailwindcss/colors'

export default <Partial<Config>>{
  theme: {},
  plugins: [],
  content: [
    `${srcDir}/components/**/*.{vue,js,ts}`,
    `${srcDir}/layouts/**/*.vue`,
    `${srcDir}/pages/**/*.vue`,
    `${srcDir}/composables/**/*.{js,ts}`,
    `${srcDir}/plugins/**/*.{js,ts}`,
    `${srcDir}/utils/**/*.{js,ts}`,
    `${srcDir}/App.{js,ts,vue}`,
    `${srcDir}/app.{js,ts,vue}`,
    `${srcDir}/Error.{js,ts,vue}`,
    `${srcDir}/error.{js,ts,vue}`,
    `${srcDir}/app.config.{js,ts}`
  ]
}

tailwind其他配置详见:Configuration - Tailwind CSS

~/assets/css/tailwind.css

@tailwind base;
@tailwind components;
@tailwind utilities;

引入第三方样式或js

Nuxt3框架全局引用外部JS/CSS文件的相关配置方法_nuxt3 配置引入js-CSDN博客

样式化 · 快速入门 Nuxt