Nuxt讲解

代码仓库

nuxt基础

内置组件

nuxt为我们提供了一些内置组件,可以直接使用不用导入,其中常用的如下

SEO组件
  • Html
  • Body
  • Head
  • Title
  • Meta
  • Style
  • Link
  • NoScript
  • Base

SEO组件可以更加方便的让我们再页面中添加利于seo的元素

NuxtWelcome

欢迎页面组件,该组件是nuxt/ui的一部分

NuxtPage

该组件时Nxut自带的页面的占位组件,是对router-view的封装,另外nuxt采用的是约定式路由,即不需要我们手动配置路由,nuxt会根据我们在pages文件夹中的文件以及app文件夹(开发中),具体的我们会在下边介绍。

NuxtLink

该组件相当于vue-router中的router-link组件,用于页面跳转
组件属性

  • to: 表示要跳转的路径
  • href: to的别名
  • replace: boolean 默认为false,是否替换当前路由
  • activeClass: 激活连接时的生效的类名
  • target: 和a标签的target一样
ClientOnly

该组件的默认插槽的内容只会再客户端渲染,而fallback插槽的内容只在服务器端渲染
在服务端渲染期间,fallback内容会被渲染,一般会显示加载信息

<template>
  <div>home</div>
  <NuxtLink to="/">home</NuxtLink>
  <div>
    <ClientOnly>
      <!-- 
        在服务端渲染期间,fallback内容会被渲染,一般会显示加载信息
       -->
      <template #fallback>
        <p>该内容只会再服务器端渲染</p>
      </template>
    </ClientOnly>
    <ClientOnly>
      <template #default>
        <p>该内容会再客户端渲染</p>
      </template>
    </ClientOnly>
  </div>
</template>
<script setup lang="ts"></script>

<style scoped></style>

(/pages/home/index.vue)

全局样式

安装sass

yarn add sass -D

新建assets文件夹,并在该文件夹中新建css文件夹,新建global.scss文件用于写一些全局样式,新建value.scss用于保存全局变量
在nuxt.config.ts中配置

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  //全局引入样式
  css: ["@/assets/css/global.scss"],
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          // 每个文件中都会加上这句话
          additionalData: "@use '@/assets/css/value.scss' as *;",
        },
      },
    },
  },
});

之后我们在/pages/index.vue中使用,就可以看到效果了

静态资源

nuxt中提供两个目录用于存放静态资源,比如:stylesheets、fonts或img

  • public
    • 可以通过**/**来获取到public目录中的文件

例如:

<img
  class="imgSty"
  src="/01.jpg"
  alt=""
  />
  • asstes
    • 可以通过**~/assets/或者@/assets/**路径径引用assets目录中的文件

例如:

<img
src="@/assets/img/01.jpg"
class="imgSty"
alt=""
  />

/pages/index.vue

pages

新建页面

  • nuxt项目的页面一般是在pages目录下创建的,不过我们在新初始化的项目中官方默认给的是app目录,这两个目录使用方法差不多,并且app目录在最新版官方文档中并没有出现,表示正在实验阶段,后续语法可能会改变,所以就不过多赘述
  • nuxt的页面路由也称为文件系统路由,我们不需要额外配置,直接根据/文件名的方式就可以访问,如果是文件夹,文件夹中的index.vue可以通过/文件夹名的方式访问,其他文件通过/文件夹名/文件名的方式访问

nuxt为我们提供了命令的方式去创建页面

# 创建home页面
npx nuxi add page home

NuxtLink

<NuxtLink to="/">home</NuxtLink>

编程式路由导航

nuxt3除了可以通过NuxtLink内置组件进行导航,也支持编程导航:navigateTo、useRouter
不过使用编程导航不利于SEO

navigateTo
基本使用

navigateTo(url,options?);

  • url表示姚导航的连接,可以是字符串也可以是路由对象
    • 路由对象:
      • path:导航的连接
      • query:query参数
  • options导航配置,可选
    • replace:默认是false,是否替换当前页面
    • external:默认是false,是否允许导航到外部连接
// 无参
navigateTo("/about", {
  replace: false,
  external: false,
});

// 有参(可以传递query参数或者params参数)
navigateTo({
  path: "/home",
  query: {
    type: "phone",
  },
});

/pages/index.vue

获取参数
const route = useRoute();
console.log(route.query);
//console.log(route.params);

/pages/home/index.vue

useRouter
常用API
const router=useRouter();
// 页面返回,类似于router.go(-1);
router.back();
// 页面前进,类似于router.go(1)
router.forward();
// 页面前进或者返回(接收一个数字)
router.go(1);
// 以push方式导航到新页面
router.push({path:"/home"});//建议使用navigateTo代替
// 以replace方式导航到新页面
router.replace({path:"/home"});//建议使用navigateTo代替
// 路由全局守卫,每次导航前执行,用于全局监听,接收一个回调函数
router.beforeEach();
// 路由守卫,每次导航后执行,用于全局监听,接收一个回调函数
router.afterEach();
获取参数

获取参数和navigateTo获取参数类似

动态路由

我们可以使用[]方括号的形式来编写动态路由,方括号里边存放是动态路由的参数

基本使用
pages/detail/[id].vue	=> /detail/:id
pages/detail/user-[id].vue => /detail/user-:id
pages/detail/[role]/[id].vue => /detail/:role/:id
获取参数

通过route.params获取传递的参数

const route = useRoute();
const id = route.params.id;

404页面

nuxt为我们提供了404页面,但是并不适用于页面展示,我们可以自己定义404页面,通过方括号内添加三个点即表示捕获所有不匹配路由
例如:[…not].vue(not是一个名字,这个可以自定义)
pages目录中新建[…not].vue

嵌套路由

再文件夹中创建一个与一级路由同名的文件夹就可以使用嵌套二级路由

- pages
---| parent/
  ----| index.vue
---| parent.vue

访问路径/parent/parent

页面布局

我们的网站中经常会遇到每个页面中都包含一样的页头以及页脚
我们就可以使用layout来进行布局
再跟目录新建layouts文件夹
页面布局可以使用两种布局方式一种是默认布局,一种是自定义布局

默认布局

在layouts目录下default.vue
然后再app.vue中通过NuxtLayout包裹

<!-- default.vue -->
<template>
  <div class="layout">
    <div>页头</div>
    <slot></slot>
    <div>页脚</div>
  </div>
</template>
<script setup lang="ts"></script>

<style scoped></style>

<!-- app.vue -->
<template>
  <div>
    <NuxtLayout>
      <!-- 默认欢迎页 -->
      <!-- <NuxtWelcome /> -->
      <!-- 占位组件 -->
      <NuxtPage></NuxtPage>
    </NuxtLayout>
  </div>
</template>

自定义布局

在layouts中新建my-layout.vue,然后通过name属性指定布局类型(命名格式不能使用大驼峰)

<!-- my-layout.vue -->
<template>
  <div>
    <div>我是自定义页头</div>
    <slot></slot>
  </div>
</template>
<script setup lang="ts"></script>

<style scoped></style>

<!-- app.vue -->
<template>
  <div>
    <NuxtLayout name="my-layout">
      <!-- 默认欢迎页 -->
      <!-- <NuxtWelcome /> -->
      <!-- 占位组件 -->
      <NuxtPage></NuxtPage>
    </NuxtLayout>
  </div>
</template>

页面中指定布局方式

我们也可以使用definePageMeta来指定当前页面布局模板,
使用时NuxtLayout不能指定布局方式否则不生效

definePageMeta({
  layout: "my-layout",
});

/pages/about/index.vue

生命周期

image.png

获取数据

我们在之前项目中,我们一般使用axios去请求数据,但是在nuxt中,官方更加推荐我们使用useFetch而不是axios

封装
import type { AsyncData, UseFetchOptions } from "nuxt/dist/app/composables";

const BASE_URL = "";
type Methods = "GET" | "POST";

class MyRequest {
  request<T = any>(
    url: string,
    method: Methods,
    data?: any,
    options?: UseFetchOptions<T>
  ): Promise<AsyncData<T, Error>> {
    return new Promise((resolve, reject) => {
      const newOptions: UseFetchOptions<T> = {
        baseURL: BASE_URL,
        method: method,
        ...options,
      };

      if (method === "GET") {
        newOptions.query = data;
      }
      if (method === "POST") {
        newOptions.body = data;
      }
      useFetch<T>(url, newOptions as any)
        .then((res) => {
          resolve(res as AsyncData<T, Error>);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  get<T = any>(url: string, params?: any, options?: UseFetchOptions<T>) {
    return this.request<T>(url, "GET", params, options);
  }

  post<T = any>(url: string, data?: any, options?: UseFetchOptions<T>) {
    return this.request<T>(url, "POST", data, options);
  }
}

export default new HYRequest();

全局状态数据共享

使用pinia去实现全局状态管理
具体使用pinia的方式我会在下一个博客中详细说明

yarn add pinia @pinia/nuxt

配置

在nuxt.config.ts中添加配置

modules: ["@pinia/nuxt"]

使用element plus

安装

yarn add element-plus

自动导入

yarn add unplugin-element-plus -D

babel 转义

yarn add unplugin-element-plus -D

nuxt.config.ts配置

// https://nuxt.com/docs/api/configuration/nuxt-config
import ElementPlus from "unplugin-element-plus/vite";

export default defineNuxtConfig({
  devtools: { enabled: true },
  css: [
    "normalize.css",
    "@/assets/css/global.scss",
    "@/assets/cus-font/iconfont.css",
  ],
  modules: ["@pinia/nuxt"],
  // 配置自动导入样式
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: "@use '@/assets/css/variables.scss' as *;",
        },
      },
    },
    plugins: [ElementPlus({})],
  },
  app: {
    // 可以给所有的页面的head添加一下SEO的信息
    head: {
      title: "",
      meta: [
        {
          name: "description",
          content:
            "",
        },
        {
          name: "keywords",
          content: "",
        },
        { name: "viewport", content: "width=device-width, initial-scale=1" },
      ],
      link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
      noscript: [{ children: "Javascript is required" }],
    },
  },
  build: {
    // 该文件需要进行Babel转义
    transpile: ["element-plus/es"],
  },
});

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值