Nuxt.js


官网 Nuxt.js


认识nuxt

nuxt通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。
Vue 开发一个单页面应用,相信很多前端工程师都已经学会了,但是单页面应用有一个致命的缺点,就是 SEO 极不友好。除非,vue 能在服务端渲染(ssr)并直接返回已经渲染好的页面,而并非只是一个单纯的 <div id="app"></div>

SSR: 服务端渲染,在服务器端把vue渲染成html返回浏览器
支持SEO:搜索引擎优化
很多需要搜索引擎来提供流量的网站都需要做SSR,适用于一个项目可能所有页面要做SEO,像新闻、博客、影视等内容网站都需要

它具有一下特性,
● 基于 Vue.js
● 自动代码分层
● 服务端渲染
● 强大的路由功能,支持异步数据
● 静态文件服务
● ES2015+ 语法支持
● 打包和压缩 JS 和 CSS
● HTML 头部标签管理
● 本地开发支持热加载
● 集成 ESLint
● 支持各种样式预处理器: SASS、LESS、 Stylus 等等
● 支持 HTTP/2 推送

学习使用nuxt

安装

● Nuxt.js 十分简单易用。一个简单的项目只需将 nuxt 添加为依赖组件即可。
● 安装node和npm等基本前端开发环境
● 确保安装了 npx(npx 在 NPM 版本 5.2.0 默认安装了)

使用

npx create-nuxt-app <项目名>
yarn create nuxt-app <项目名>
它会让你进行一些选择:

  1. 在集成的服务器端框架之间进行选择:
    ● None (Nuxt 默认服务器)
    ● Express
    ● Koa
    ● Hapi
    ● Feathers
    ● Micro
    ● Fastify
    ● Adonis (WIP)
  2. 选择您喜欢的 UI 框架:
    ● None (无)
    ● Bootstrap
    ● Vuetify
    ● Bulma
    ● Tailwind
    ● Element UI
    ● Ant Design Vue
    ● Buefy
    ● iView
    ● Tachyons
  3. 选择您喜欢的测试框架:
    ● None (随意添加一个)
    ● Jest
    ● AVA
  4. 选择你想要的 Nuxt 模式 (Universal or SPA)
  5. 添加 axios module 以轻松地将 HTTP 请求发送到您的应用程序中。
  6. 添加 EsLint 以在保存时代码规范和错误检查您的代码。
  7. 添加 Prettier 以在保存时格式化/美化您的代码。
    Project name——项目名称
    Programming language——程序设计语言
    Package manager——包管理器
    UI framework——UI框架
    Nuxt.js modules——NuxtJS模块(如果需要安装某个需要按"空格"电亮才行)
    Linting tools——代码校验工具
    Testing framework——测试框架
    Universal——渲染模式(SSR:服务端渲染、SSG:静态页面生成)
    Deployment target——部署目标
    Development tools——开发工具
    What is your GitHub username?——GitHub名称
    Version control system——版本控制工具
npm run dev

目录结构(Nuxt 与 VueCli 对比)

pages——页面(类似于:src/views)
components——组件(类似于:src/components)
static——静态资源(类似于:scr/assets)
store——vuex状态树(类似于:src/store)
muxt.config.js——全局配置文件(类似于:vue.config.js)
├── .nuxt/ # 自动生成的文件,包含编译后的代码和配置
├── assets/ # 用于存放未编译的静态资源,如CSS、图片、字体
├── components/ # 自定义Vue组件
├── layouts/ # 应用的布局文件,定义页面的通用结构
│ └── default.vue # 默认布局
├── middleware/ # 中间件文件,可以在页面渲染前后执行逻辑
├── pages/ # 应用的路由和视图,每个文件对应一个路由
│ ├── index.vue # 默认首页
│ └── [slug].vue # 动态路由示例
├── plugins/ # 自定义Vue.js插件
├── static/ # 静态资源,会被原样复制到输出目录
├── store/ # Vuex状态管理文件
│ ├── actions.js # Vuex actions
│ ├── mutations.js # Vuex mutations
│ ├── getters.js # Vuex getters
│ └── index.js # Vuex store入口文件
├── nuxt.config.js # Nuxt.js配置文件
├── package.json # 项目依赖和脚本
└── yarn.lock # 或者npm.lock,记录依赖版本
在这里插入图片描述


服务端生命周期

nuxt的生命周期分为客户端生命周期,服务端生命周期

客户端生命周期(SPA)

beforeCreate:在实例初始化之后,数据观测(data observer)和事件/watcher 设置之前调用。
created:在实例创建完成后被调用,在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount:在挂载开始之前调用,相关的 render 函数首次被调用。
mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。
beforeUpdate:数据更新时调用,此时虚拟 DOM 已创建完毕,但尚未被实际的 DOM 替换。
updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
beforeDestroy:实例销毁之前调用。
destroyed:实例销毁后调用,此时所有的事件监听器会被移除,所有的子实例也会被销毁。

服务端生命周期(SSR)

nuxtServerInit(store,context){}:类似于vue.js中的main.js。可以在这个生命周期中获取token并存储。store为vuex上下文,context 为nuxt上下文
middleware({store,route,redirect,params,query,req,res}){}:类似于vue.js中的导航守卫,可以是全局的,路由的,组件的。可以在这个生命周期中进行用户是否登录判断,在全局nuxt.config.js进行配置,中间件运行,有三种

// 在nuxt.config.js中配置,如下
module.exports = {
    router:{
        // 指在运行时,指定运行 middlewrae 文件夹下的 auth.js
        middleware: 'auth'
    }
}
// 在布局layouts里配置
export default {
  // 法一:定义在外部即middleware文件夹里
  middleware: 'auth'
  // 法二:定义在内部
  middleware(context){
    consle.log('布局级 middleware');
  }
}
// pages文件夹下的任意一个页面
middleware(context){
  consle.log('页面级 middleware');
}

顺序依次为:nuxt.config.js -> layouts - > page

validate(仅适用于asyncData和validate):在服务端渲染页面之前调用,页面还没有初始化时会先校验参数。

validate({params, query}){
  return 校验结果 true/false
  // 成功:正常显示页面
  // 失败:跳转404页面
}

asyncData:异步处理数据,在服务端渲染页面之前调用,可以接收请求的上下文,可以进行数据请求。
// 这里返回的数据会和当前页面的data进行合并,即用this.test就可访问到返回的数据

asyncData(context){
  return {
    test: '返回的数据'
  }
}

fetch:异步处理数据,在服务端渲染页面之后,客户端渲染页面之前调用,可以进行数据请求,读取服务端数据提交给vuex。

fetch({store}){
  ...
}

head:用于设置页面的meta信息,在nuxt.config.js中能设置全局的标签。
beforeCreated(SSR和SPA):在实例初始化之后调用。
created(SSR和SPA):在实例被创建之后调用。

在这里插入图片描述


Nuxt路由

路由跳转的三种方式

a连接的形式跳转

<a href="/list?id=1">a连接的形式跳转</a><br/>

链接的方式跳转

<nuxt-link :to="{name:'list',query:{id:1},params:{id:2}}">Link的方式</nuxt-link><br/>

js跳转

<template>
  <button @click="toList">js跳转</button><br/>
</template>
<script>
  toList(){
    this.$router.push({
      path:'/list',
      query:{
        id:123
      },
      params:{
        id:321
      }
    });
  }
</script>

使用已有的VueCli路由文件
● 安装插件

npm install @nuxtjs/router -S

● 在【nuxt.config.js】文件的【modules】模块中配置。

modules: [
  '@nuxtjs/router'
],

● 在根路径删新建一个【router.js】文件,文件名必须为router。

正常引入之后就是在router.js文件中进行和vue中一样的路由配置,同样也可以进行路由守卫的各种配置

路由守卫

● 有两种方式

router.js

vue-cli中怎么用,next中就怎么用,几乎一样。

//全局导航守卫
router.beforeEach((to,from,next)=>{
  if(to.name=="About"){
    next("/news")
  }else{
    next()
  }
})
NuxtJS中间件或插件

● 中间件:middleware生命周期创建路由守卫

// 全局:
// nuxt.config.js配置
module.exports = {
    router:{
        // 指在运行时,指定运行 middlewrae 文件夹下的 auth.js
        middleware: 'auth'
    }
}
// 全局导航守卫 即配置文件中指向的auth.js文件
export default function(store,route,redirect,parms,query,req,res){    
  console.log("路由守卫")
}


// 局部:页面级
// 法一:定义在外部即middleware文件夹里
  middleware: 'auth'
  // 法二:定义在内部
  middleware(context){
    consle.log('布局级 middleware');
  }

● 插件:plugins

// 在【nuxt.config.js】的plugins进行配置
plugins: [
  '~/plugins/router.js'
], // 指向plugins文件夹下面的router.js文件
// plugins文件夹下新建一个router.js文件进行配置
export default ({app}) => {
  // 全局
  app.router.beforeEach((to,from,next)=>{
    console.log(to)
    next();
  })
}

Vuex

Nuxt.js 自动创建了一个 Vuex store。在 store 目录下,你可以创建模块化的 state、mutations、actions 和 getters。例如,创建一个 store/modules/users.js 文件来管理用户数据。
用法和在vue-cli中差不多

页面渲染
在pages/目录下创建一个index.vue文件,这是应用的首页:

<template>
  <div>
    <h1>Hello from Nuxt.js SSR</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        message: 'This content is server-rendered!'
      };
    },
    asyncData() {
      // 这里可以在服务器端获取数据
      // 返回的数据会作为data的默认值
      return { message: 'Data fetched on server' };
    }
  };
</script>

Nuxt.js 页面渲染的过程分为两个主要阶段:服务器端渲染 (SSR) 和客户端渲染 (CSR)。以下是Nuxt.js页面渲染的详细步骤:

初始化

用户在浏览器中输入URL并发送请求到服务器。
服务器接收到请求后,开始处理。

路由解析

Nuxt.js 使用 nuxt.config.js 中的 routes 配置(如果存在)或自动从 pages/ 目录生成路由。
对应的页面文件被识别,例如 pages/index.vue 或 pages/about.vue。

数据预取

Nuxt.js 查找页面组件中的 asyncData 或 fetch 方法(如果存在)。
这些方法会在服务器端运行,用于从API或其他数据源获取数据。
数据获取后,会被序列化并注入到页面模板中。

模板渲染

Nuxt.js 使用 Vue.js 的渲染引擎将组件和预取的数据转换为HTML字符串。
HTML字符串中包含了客户端需要的所有初始数据,以JSON格式内联在

返回HTML

服务器将生成的HTML响应发送回客户端(浏览器)。

客户端初始化:

浏览器接收到HTML后,开始解析和执行内联的JavaScript。
Nuxt.js客户端库(nuxt.js)被加载并初始化。

客户端渲染

客户端库接管渲染,Vue.js实例被创建,数据从内联的JSON注入到Vue实例。
页面完成初始渲染,用户可以看到完整的页面内容。
此时,页面是交互式的,用户可以触发事件和导航。

后续导航

当用户导航到其他页面时,Nuxt.js 使用客户端路由(Vue Router)进行无刷新跳转。
如果新页面需要数据,asyncData 或 fetch 方法会在客户端运行,获取新的数据并更新视图。

SSG(静态站点生成)

在开发之外,可以使用 nuxt generate 命令生成静态HTML文件。
每个页面都会被预渲染为独立的HTML文件,其中包含所有必要的数据和资源。

使用asyncData

asyncData方法是Nuxt.js特有的,它允许你在服务器端预取数据并在客户端复用这些数据。在上面的示例中,我们简单地更改了message的值,但在实际应用中,你可能会在这里调用API获取数据。


Nuxt.js 配置文件(nuxt.config.js)

export default {
  // 项目名称
  name: 'nuxt-demo',

  // 项目模式:spa, universal, static
  mode: 'universal', // 默认值,支持服务器端渲染

  // 应用元信息
  head: {
    title: 'My Nuxt App',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'App description' }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  },

  // CSS样式
  css: [
    '@/assets/css/main.css'
  ],

  // 路由配置
  router: {
    base: '/nuxt-demo/', // 应用的基础路径
    extendRoutes(routes, resolve) {
      // 手动扩展或修改路由
    }
  },

  // 构建配置
  build: {
    transpile: [/^my-vue-component/], // 需要转译的模块
    vendor: ['lodash'], // 公共库,提前打包
    extractCSS: true, // 提取CSS到单独文件
    optimization: {
      splitChunks: {
        cacheGroups: {
          vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            filename: 'vendors.js'
          }
        }
      }
    }
  },

  // Axios配置
  axios: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000/api', // API基础URL
    browserBaseURL: 'https://api.example.com' // 客户端的API基础URL
  },

  // Plugins
  plugins: [
    { src: '@/plugins/vue-my-plugin', ssr: false } // 异步加载的插件,ssr: false 表示仅客户端加载
  ],

  // Modules
  modules: [
    '@nuxtjs/axios', // 安装并配置axios模块
    '@nuxtjs/pwa' // 安装并配置PWA模块
  ],

  // 环境变量
  env: {
    apiKey: 'your-api-key',
    apiUrl: 'https://api.example.com'
  },

  // Vuex Store配置
  store: true, // 自动创建Vuex store
  loading: { color: '#3B8070' }, // 加载指示器颜色

  // 服务端中间件
  serverMiddleware: [
    { path: '/api', handler: '~/api/index.js' } // 使用自定义的服务器端中间件
  ],

  // 静态生成配置
  generate: {
    dir: 'dist', // 输出目录
    fallback: true, // 对未预渲染的动态路由生成404页面
    routes: () => ['/about', '/contact'] // 预渲染的指定路由
  }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值