阐述 Nuxt.js 作为 Vue SSR 框架的核心功能和优势,例如约定式路由、数据获取方法等。

各位观众老爷们,大家好!我是今天的讲师,咱们今天聊聊 Nuxt.js 这个 Vue SSR 的神器。别怕,SSR听着高大上,其实就是让你的 Vue 应用在服务器上跑起来,然后把渲染好的 HTML 直接送到浏览器,而不是让浏览器自己吭哧吭哧地渲染。

Nuxt.js 就像一个贴心的管家,帮你把 Vue SSR 的各种坑都填平了,让你可以专注于写业务逻辑,而不是跟那些复杂的配置死磕。

一、Nuxt.js 的核心功能:约定大于配置

Nuxt.js 最大的特点就是“约定大于配置”,这意味着它已经为你定义好了一套标准的项目结构和开发模式,你只需要按照它的规则来,就能省去大量的配置工作。

  1. 目录结构:一切皆文件

Nuxt.js 对目录结构有严格的要求,不同的目录负责不同的功能。

目录 功能
pages/ 存放你的页面组件,Nuxt.js 会自动根据 pages 目录下的文件结构生成路由。比如 pages/index.vue 对应 /pages/about.vue 对应 /aboutpages/users/[id].vue 对应 /users/:id
layouts/ 存放你的布局组件,比如网站的头部、底部、侧边栏等。你可以定义不同的布局,并在页面中使用。默认布局是 layouts/default.vue
components/ 存放你的通用组件,比如按钮、输入框、弹窗等。这些组件可以在多个页面中使用。
assets/ 存放你的静态资源,比如 CSS、图片、字体等。这些资源会被 Webpack 处理。
static/ 存放你的静态文件,比如 robots.txtfavicon.ico 等。这些文件会被直接复制到 dist 目录。
plugins/ 存放你的 Vue 插件,比如 Vuex、Axios 等。你可以在 nuxt.config.js 中配置需要加载的插件。
middleware/ 存放你的中间件,比如权限验证、日志记录等。中间件可以在路由跳转前后执行。
store/ 存放你的 Vuex store 文件。如果启用了 Vuex 模块模式,Nuxt.js 会自动根据 store 目录下的文件结构生成 Vuex 模块。
nuxt.config.js Nuxt.js 的配置文件,你可以在这里配置各种选项,比如服务器端口、CSS 预处理器、插件、模块等。

举个例子,如果你想创建一个 /users/123 这样的路由,只需要在 pages 目录下创建一个 users 目录,然后在 users 目录下创建一个 [id].vue 文件即可。

pages/users/[id].vue:

<template>
  <div>
    <h1>User ID: {{ id }}</h1>
  </div>
</template>

<script>
export default {
  computed: {
    id() {
      return this.$route.params.id;
    }
  }
}
</script>

Nuxt.js 会自动帮你生成对应的路由,你只需要关注组件的逻辑即可。

  1. 约定式路由:告别手写路由表

上面已经提到了,Nuxt.js 会自动根据 pages 目录下的文件结构生成路由。这意味着你不需要手动编写路由表,只需要按照 Nuxt.js 的规则来创建文件,就能自动生成对应的路由。

例如,pages/about/index.vue 对应 /aboutpages/blog/[slug].vue 对应 /blog/:slug

如果你需要更复杂的路由,可以使用动态路由和通配符路由。

  • 动态路由: 就像上面的例子,使用 [id].vue 这样的文件名来定义动态路由参数。
  • 通配符路由: 使用 [...slug].vue 这样的文件名来定义通配符路由,可以匹配任意数量的路径段。例如,pages/blog/[...slug].vue 可以匹配 /blog/a/blog/a/b/blog/a/b/c 等。
  1. 数据获取:告别手动请求

Nuxt.js 提供了多种数据获取方法,让你可以在组件渲染之前获取数据。

  • asyncData: 在组件渲染之前在服务器端获取数据。这个方法会在服务器端执行一次,然后将数据传递给客户端。这对于 SEO 非常重要,因为搜索引擎可以抓取到服务器端渲染的内容。
  • fetch: 类似于 asyncData,也是在组件渲染之前获取数据。但是,fetch 方法可以在服务器端和客户端都执行。如果需要在客户端更新数据,可以使用 fetch 方法。

这两个方法都返回一个 Promise,Nuxt.js 会在 Promise resolve 之后再渲染组件。

pages/index.vue:

<template>
  <div>
    <h1>Welcome</h1>
    <ul>
      <li v-for="post in posts" :key="post.id">
        {{ post.title }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios }) {
    const { data } = await $axios.$get('https://jsonplaceholder.typicode.com/posts');
    return { posts: data };
  }
}
</script>

在这个例子中,asyncData 方法使用 $axios 插件来获取数据,然后将数据返回给组件。Nuxt.js 会在服务器端执行 asyncData 方法,然后将数据传递给客户端。

注意点: asyncData 里面不能使用 this,因为它是在组件实例化之前执行的。如果要访问组件的 this,可以使用 fetch 方法或者在 mounted 钩子函数中获取数据。

二、Nuxt.js 的优势:不止于 SSR

Nuxt.js 不仅仅是一个 Vue SSR 框架,它还提供了很多其他的优势。

  1. SEO 友好:提升你的网站排名

SSR 可以让搜索引擎抓取到你的网站内容,从而提升你的网站排名。Nuxt.js 默认开启 SSR,你不需要做任何额外的配置。

  1. 首屏加载速度快:用户体验更佳

SSR 可以让浏览器直接接收到渲染好的 HTML,而不需要等待 JavaScript 加载和执行。这可以大大缩短首屏加载时间,提升用户体验。

  1. 更好的用户体验:告别白屏

使用 Nuxt.js 可以避免白屏现象,因为服务器端已经渲染好了页面,浏览器可以直接显示内容。

  1. 强大的模块系统:扩展你的应用

Nuxt.js 提供了强大的模块系统,你可以使用各种模块来扩展你的应用功能。比如,你可以使用 @nuxtjs/axios 模块来简化 HTTP 请求,使用 @nuxtjs/pwa 模块来将你的网站变成 PWA 应用。

  1. 自动代码分割:优化你的应用

Nuxt.js 会自动对你的代码进行分割,将不同的页面和组件打包成不同的 chunk。这可以减少首屏加载的 JavaScript 代码量,提升性能。

  1. 热模块替换:提升开发效率

Nuxt.js 支持热模块替换(HMR),这意味着你修改代码后,浏览器会自动刷新,而不需要手动刷新页面。这可以大大提升开发效率。

三、Nuxt.js 的数据获取方法:深入解析

上面提到了 asyncDatafetch 两个数据获取方法,这里我们再深入解析一下它们。

方法 执行时机 执行环境 是否可访问 this 适用场景
asyncData 组件实例化之前 服务器端 适用于需要在服务器端获取数据,且数据不需要在客户端更新的场景。例如,获取文章列表、用户信息等。
fetch 组件实例化之前和之后 服务器端和客户端 适用于需要在服务器端和客户端都获取数据,或者需要在客户端更新数据的场景。例如,获取商品列表、购物车信息等。
mounted 组件挂载之后 客户端 适用于只需要在客户端获取数据的场景。例如,获取用户地理位置、播放视频等。

asyncData 的使用场景

asyncData 适用于需要在服务器端获取数据,且数据不需要在客户端更新的场景。

pages/about.vue:

<template>
  <div>
    <h1>About Us</h1>
    <p>{{ description }}</p>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios }) {
    const { data } = await $axios.$get('https://your-api.com/about');
    return { description: data.description };
  }
}
</script>

在这个例子中,asyncData 方法从 API 获取关于我们的描述信息,并将数据返回给组件。

fetch 的使用场景

fetch 适用于需要在服务器端和客户端都获取数据,或者需要在客户端更新数据的场景。

pages/products.vue:

<template>
  <div>
    <h1>Products</h1>
    <ul>
      <li v-for="product in products" :key="product.id">
        {{ product.name }} - ${{ product.price }}
      </li>
    </ul>
    <button @click="loadMore">Load More</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: [],
      page: 1
    };
  },
  async fetch() {
    const { data } = await this.$axios.$get(`https://your-api.com/products?page=${this.page}`);
    this.products = this.products.concat(data);
  },
  methods: {
    loadMore() {
      this.page++;
      this.$fetch(); // 触发 fetch 方法,加载更多数据
    }
  }
}
</script>

在这个例子中,fetch 方法从 API 获取商品列表,并将数据添加到组件的 products 数组中。当点击 "Load More" 按钮时,会触发 fetch 方法,加载更多数据。

mounted 的使用场景

mounted 钩子函数适用于只需要在客户端获取数据的场景。

pages/location.vue:

<template>
  <div>
    <h1>Your Location</h1>
    <p>Latitude: {{ latitude }}</p>
    <p>Longitude: {{ longitude }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      latitude: null,
      longitude: null
    };
  },
  mounted() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position => {
        this.latitude = position.coords.latitude;
        this.longitude = position.coords.longitude;
      });
    } else {
      alert("Geolocation is not supported by this browser.");
    }
  }
}
</script>

在这个例子中,mounted 钩子函数使用 navigator.geolocation API 获取用户的地理位置,并将数据更新到组件的状态中。

四、Nuxt.js 的中间件:控制你的路由

Nuxt.js 的中间件可以在路由跳转前后执行,可以用来做权限验证、日志记录等。

  1. 定义中间件

middleware 目录下创建一个文件,比如 middleware/auth.js

middleware/auth.js:

export default function ({ store, redirect }) {
  // 如果用户未登录,则重定向到登录页面
  if (!store.state.auth.loggedIn) {
    return redirect('/login');
  }
}
  1. 使用中间件

你可以在页面组件或者 nuxt.config.js 中使用中间件。

  • 页面组件:

pages/profile.vue:

<template>
  <div>
    <h1>Profile</h1>
    <p>Welcome, {{ user.name }}!</p>
  </div>
</template>

<script>
export default {
  middleware: ['auth'], // 使用 auth 中间件
  computed: {
    user() {
      return this.$store.state.auth.user;
    }
  }
}
</script>
  • nuxt.config.js:

nuxt.config.js:

export default {
  router: {
    middleware: ['auth'] // 全局使用 auth 中间件
  }
}

在这个例子中,auth 中间件会检查用户是否已登录。如果用户未登录,则重定向到登录页面。

五、Nuxt.js 的模块:扩展你的应用

Nuxt.js 提供了强大的模块系统,你可以使用各种模块来扩展你的应用功能。

  1. 安装模块

使用 npm 或者 yarn 安装模块。

npm install @nuxtjs/axios
# 或者
yarn add @nuxtjs/axios
  1. 配置模块

nuxt.config.js 中配置需要加载的模块。

nuxt.config.js:

export default {
  modules: [
    '@nuxtjs/axios'
  ],
  axios: {
    baseURL: 'https://your-api.com'
  }
}

在这个例子中,我们安装并配置了 @nuxtjs/axios 模块。

常用的 Nuxt.js 模块

模块 功能
@nuxtjs/axios 简化 HTTP 请求,提供 $axios 插件。
@nuxtjs/pwa 将你的网站变成 PWA 应用,提供离线访问、推送通知等功能。
@nuxtjs/auth-next 提供用户认证功能,支持多种认证方式,比如 JWT、OAuth 等。
@nuxtjs/content 基于 Markdown 和 YAML 文件的内容管理系统,可以用来构建博客、文档站点等。
@nuxtjs/sitemap 自动生成 sitemap.xml 文件,方便搜索引擎抓取你的网站内容。
@nuxtjs/robots 自动生成 robots.txt 文件,控制搜索引擎的抓取行为。

六、Nuxt.js 的部署:让你的应用上线

Nuxt.js 提供了多种部署方式,你可以根据你的需求选择合适的部署方式。

  1. 静态站点部署

如果你不需要 SSR,可以将你的 Nuxt.js 应用生成静态站点,然后部署到 Netlify、Vercel 等静态站点托管平台。

nuxt generate

这个命令会将你的 Nuxt.js 应用生成静态 HTML 文件,然后你可以将这些文件部署到静态站点托管平台。

  1. 服务器端部署

如果你需要 SSR,可以将你的 Nuxt.js 应用部署到 Node.js 服务器。

  • PM2: 使用 PM2 管理你的 Node.js 进程。
  • Docker: 使用 Docker 容器化你的应用。

总结

Nuxt.js 是一个非常强大的 Vue SSR 框架,它提供了很多开箱即用的功能,可以帮助你快速构建高性能、SEO 友好的 Vue 应用。虽然学习曲线可能会稍微陡峭一些,但是一旦掌握了它的核心概念,你就会发现它真的是一个非常棒的框架。

好了,今天的讲座就到这里,希望对大家有所帮助! 散会!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注