各位观众老爷们,大家好!我是今天的讲师,咱们今天聊聊 Nuxt.js 这个 Vue SSR 的神器。别怕,SSR听着高大上,其实就是让你的 Vue 应用在服务器上跑起来,然后把渲染好的 HTML 直接送到浏览器,而不是让浏览器自己吭哧吭哧地渲染。
Nuxt.js 就像一个贴心的管家,帮你把 Vue SSR 的各种坑都填平了,让你可以专注于写业务逻辑,而不是跟那些复杂的配置死磕。
一、Nuxt.js 的核心功能:约定大于配置
Nuxt.js 最大的特点就是“约定大于配置”,这意味着它已经为你定义好了一套标准的项目结构和开发模式,你只需要按照它的规则来,就能省去大量的配置工作。
- 目录结构:一切皆文件
Nuxt.js 对目录结构有严格的要求,不同的目录负责不同的功能。
目录 | 功能 |
---|---|
pages/ | 存放你的页面组件,Nuxt.js 会自动根据 pages 目录下的文件结构生成路由。比如 pages/index.vue 对应 / ,pages/about.vue 对应 /about ,pages/users/[id].vue 对应 /users/:id 。 |
layouts/ | 存放你的布局组件,比如网站的头部、底部、侧边栏等。你可以定义不同的布局,并在页面中使用。默认布局是 layouts/default.vue 。 |
components/ | 存放你的通用组件,比如按钮、输入框、弹窗等。这些组件可以在多个页面中使用。 |
assets/ | 存放你的静态资源,比如 CSS、图片、字体等。这些资源会被 Webpack 处理。 |
static/ | 存放你的静态文件,比如 robots.txt 、favicon.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 会自动帮你生成对应的路由,你只需要关注组件的逻辑即可。
- 约定式路由:告别手写路由表
上面已经提到了,Nuxt.js 会自动根据 pages
目录下的文件结构生成路由。这意味着你不需要手动编写路由表,只需要按照 Nuxt.js 的规则来创建文件,就能自动生成对应的路由。
例如,pages/about/index.vue
对应 /about
,pages/blog/[slug].vue
对应 /blog/:slug
。
如果你需要更复杂的路由,可以使用动态路由和通配符路由。
- 动态路由: 就像上面的例子,使用
[id].vue
这样的文件名来定义动态路由参数。 - 通配符路由: 使用
[...slug].vue
这样的文件名来定义通配符路由,可以匹配任意数量的路径段。例如,pages/blog/[...slug].vue
可以匹配/blog/a
、/blog/a/b
、/blog/a/b/c
等。
- 数据获取:告别手动请求
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 框架,它还提供了很多其他的优势。
- SEO 友好:提升你的网站排名
SSR 可以让搜索引擎抓取到你的网站内容,从而提升你的网站排名。Nuxt.js 默认开启 SSR,你不需要做任何额外的配置。
- 首屏加载速度快:用户体验更佳
SSR 可以让浏览器直接接收到渲染好的 HTML,而不需要等待 JavaScript 加载和执行。这可以大大缩短首屏加载时间,提升用户体验。
- 更好的用户体验:告别白屏
使用 Nuxt.js 可以避免白屏现象,因为服务器端已经渲染好了页面,浏览器可以直接显示内容。
- 强大的模块系统:扩展你的应用
Nuxt.js 提供了强大的模块系统,你可以使用各种模块来扩展你的应用功能。比如,你可以使用 @nuxtjs/axios
模块来简化 HTTP 请求,使用 @nuxtjs/pwa
模块来将你的网站变成 PWA 应用。
- 自动代码分割:优化你的应用
Nuxt.js 会自动对你的代码进行分割,将不同的页面和组件打包成不同的 chunk。这可以减少首屏加载的 JavaScript 代码量,提升性能。
- 热模块替换:提升开发效率
Nuxt.js 支持热模块替换(HMR),这意味着你修改代码后,浏览器会自动刷新,而不需要手动刷新页面。这可以大大提升开发效率。
三、Nuxt.js 的数据获取方法:深入解析
上面提到了 asyncData
和 fetch
两个数据获取方法,这里我们再深入解析一下它们。
方法 | 执行时机 | 执行环境 | 是否可访问 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 的中间件可以在路由跳转前后执行,可以用来做权限验证、日志记录等。
- 定义中间件
在 middleware
目录下创建一个文件,比如 middleware/auth.js
。
middleware/auth.js
:
export default function ({ store, redirect }) {
// 如果用户未登录,则重定向到登录页面
if (!store.state.auth.loggedIn) {
return redirect('/login');
}
}
- 使用中间件
你可以在页面组件或者 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 提供了强大的模块系统,你可以使用各种模块来扩展你的应用功能。
- 安装模块
使用 npm 或者 yarn 安装模块。
npm install @nuxtjs/axios
# 或者
yarn add @nuxtjs/axios
- 配置模块
在 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 提供了多种部署方式,你可以根据你的需求选择合适的部署方式。
- 静态站点部署
如果你不需要 SSR,可以将你的 Nuxt.js 应用生成静态站点,然后部署到 Netlify、Vercel 等静态站点托管平台。
nuxt generate
这个命令会将你的 Nuxt.js 应用生成静态 HTML 文件,然后你可以将这些文件部署到静态站点托管平台。
- 服务器端部署
如果你需要 SSR,可以将你的 Nuxt.js 应用部署到 Node.js 服务器。
- PM2: 使用 PM2 管理你的 Node.js 进程。
- Docker: 使用 Docker 容器化你的应用。
总结
Nuxt.js 是一个非常强大的 Vue SSR 框架,它提供了很多开箱即用的功能,可以帮助你快速构建高性能、SEO 友好的 Vue 应用。虽然学习曲线可能会稍微陡峭一些,但是一旦掌握了它的核心概念,你就会发现它真的是一个非常棒的框架。
好了,今天的讲座就到这里,希望对大家有所帮助! 散会!