当前位置: 首页 > 工具软件 > Nuxt.js > 使用案例 >

Nuxt.js总结

楚帅
2023-12-01

Nuxt.js是什么

官网:https://nuxtjs.org/

Nuxt.js 是一个基于 Vue.js 的服务端渲染应用框架,它可以帮我们轻松的实现同构应用。

通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI渲染。

我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。

Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。

除此之外,我们还提供了一种命令叫: nuxt generate ,为基于 Vue.js 的应用提供生成对应的静态站点的功能。

我们相信这个命令所提供的功能,是向开发集成各种微服务(Microservices)的 Web 应用迈开的新一 步。

作为框架,Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如异步数据 加载、中间件支持、布局支持等非常实用的功能。

特性

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

创建项目

Nuxt提供两种方式创建项目:

  • 使用create-nuxt-app工具
  • 手动创建

使用手动创建过程:

1. 初始化项目目录并安装nuxt

# 创建示例项目
mkdir nuxt-js
# 进入示例项目目录中
cd nuxt-js
# 初始化 package.json 文件
npm init -y
# 安装 nuxt
npm innstall nuxt

在package.json中scripts添加

  "scripts": {
    "dev": "nuxt --open",
  },

2. 创建页面并启动项目

在根目录下创建pages目录,并创建index.vue文件

pages/
--| index.vue

启动项目

npm run dev

3. Nuxt中创建路由

Nuxt会跟据pages目录中的所有.vue文件生成应用的路由配置

假设 pages 的目录结构如下:

pages/
--| users/
-----| edit.vue
--| index.vue

那么,Nuxt自动生成路由配置如下(注意:直接创建.vue文件,自动生成)

 routes: [
   {
    path: "/users/edit",
    component: pages/users/edit,
    name: "users-edit"
   },
   {
    path: "/",
    component: pages/users/index,
    name: "index"
   }
  ],

Nuxt路由

Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。

1、路由导航

  • a标签
  • <nuxt-link>组件
  • 编程时导航

2、动态路由

在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。 以下目录结构:

pages/
--| users/
-----| _id.vue
--| _dynamic/
-----| index.vue
--| index.vue

Nuxt生成对应的路由配置表为:

 routes: [
   {
    path: "/users/:id",
    component: pages/users/_id,
    name: "users-id"
   },
   {
    path: "/:dynamic.vue",
    component: pages/_dynamic.vue/index,
    name: "dynamic.vue"
   },
   {
    path: "/",
    component: pages/user/index,
    name: "index"
   },
  ],

3、嵌套路由

创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。

需要在父组件中增加<nuxt-child/>用于显示子视图内容

pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue

Nuxt.js 自动生成的路由配置如下:

routes: [
         {
            path: '/users',
            component: 'pages/users.vue',
            children: [
                {
                    path: '',
                    component: 'pages/users/index.vue',
                    name: 'users'
                },
                {
                    path: ':id',
                    component: 'pages/users/_id.vue',
                    name: 'users-id'
                }
            ]
         }
    ]

4、自定义路由配置
在 Nuxt.js 里面自定义路由,需要将动态路由_id.vue文件改为detail.vue文件。 以下目录结构:

改为文件只要不是下划线定义的都可以,如果不将_id.vue改为detail.vue则跳入动态路由_id.vue页面

pages/
--| users/
-----| detail.vue
-----| index.vue
-----| edit.vue

创建nuxt.config.js文件配置自定义路由

export default {
    // nuxt配置自定义路由模块
    router: {
        // 扩展路由配置
        extendRoutes (routes, resolve) {
            routes.push(
                {
                //将detail.vue改为动态路由
                    name: 'users/detail',
                    path: '/users/(\\d+)',
                    component: resolve(__dirname, '@/pages/users/detail.vue')
                },
                {
                //将http://localhost:3000/users/edit修改为http://localhost:3000/users/edit.html
                    name: 'users/edit',
                    path: '/users/edit.html',
                    component: resolve(__dirname, '@/pages/users/edit')
                },
                {
                //将http://localhost:3000/users/edit修改为http://localhost:3000/users/b1_x2
                    name: 'users1',
                    path: '/users/:id?',
                    component: resolve(__dirname, '@/pages/users/index.vue')
                },
                {
                //将http://localhost:3000/users/edit修改为http://localhost:3000/users/b1_x2/p1.html
                    name: 'users2',
                    path: '/users/:id/p(\\d+)\.html',
                    component: resolve(__dirname, '@/pages/users/index.vue')
                },
            )
        }
    }
}

组件

1. 全局组件

  • 根目录下创建components目录,在components目录下创建Header.vue文件,以下目录结构:
根目录/
--| components/
-----| Header.vue
  • nuxt.config.js中启用全局组件:
export default {
    components: true,
}
  • 页面中直接使用(注意不需要导入)
<template>
    <div>
        <Header/>
    </div>
</template>

2. 局部组件

  • 根目录下创建components_page(自定义)目录,在components_page目录下创建Header.vue文件,以下目录结构:
根目录/
--| components_page/
-----| Header.vue
  • 页面中使用
<template>
    <div>
        <Header/>
        <nuxt />
        <Footer/>
    </div>
</template>

<script>
import Footer from "@/components_page/Footer";
export default {
    components:{
        Footer,
    },
    data () {
        return {

        };
    },
};
</script>

布局

根目录下创建layouts目录,default.vue为默认布局组件,以下目录结构:

根目录/
--| layouts/
-----| default.vue
  • 默认布局
<template>
    <div>
        <!-- 类似于页面入口 -->
        <Header/>
        <nuxt />
        <Footer/>
    </div>
</template>
<script>
import Footer from "@/components_page/Footer";
export default {
    components:{
        Footer,
    },
    data () {
        return {

        };
    },
};
</script>

<style scoped lang="scss">
</style>

  • 自定义布局

新增boo.vue组件

根目录/
--| layouts/
-----| default.vue
-----| boo.vue

在pages中需要页面中添加layout: “boo”,

<template>
    <div>
        users_index
    </div>
</template>

<script>
export default {
    // 默认layout设置自定义的布局组件 未设置的路由还会走默认的布局组件
    layout: "boo",
    data () {
        return {

        };
    },
};
</script>

<style scoped lang="scss">
</style>

nuxt.config.js配置head

// nuxt.config.js
    head: {
        title: 'nuxt',
        htmlAttrs: {
            lang: 'zh'
        },
        meta: [
            { charset: 'utf-8' },
            { name: 'viewport', content: 'width=device-width, initial-scale=1' },
            { 'http-equiv': "X-UA-Compatible", content: 'IE=edge,chrome=1' },
            { name: 'format-detection', content: 'telephone=no' },
            { name: 'referrer', content: 'origin' }
        ],
        link: [
            { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
        ],
        script: [],
    },

请求数据

  • Nuxt.js增加了一个叫 asyncData 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。
// 当你想要动态页面内容有利于 SEO 或者是提升首屏渲染速度的时候,就在 asyncData 中发请求拿数据
// 注意事项:1.只能在页面组件中使用,子组件中可通过props获取父组件异步数据 2.没有this,在组件初始化之前被调用
// 调用时机:1.获取服务端渲染数据(确保异步数据在渲染到客户端之前已经填充渲染完成,提高渲染速度,有利于SEO) 2.客户端路由更新之前也会被调用
    async asyncData (context) {
    //获取上下文对象
    console.log(context)
    // 此时输出在服务端执行
    // 在浏览器也会输出 包裹在Nuxt SSR中
    const res = await axios({
        method: 'GET',
        url: '/pc/story/index'
    })
    // 返回的对象可以直接在页面组件使用
    // 在vue调试工具中有了posts和title
    // asyncData返回的数据会和data中的混合
        return {
           list: res,
        }
    },

    // 如果是非异步数据或者普通数据,则正常的初始化到 data 中即可
    data () {
        return {
            list: [],
        }
    }
  • Nuxt.js在最新发布的2.12版本中引入了一个新的方法-- fetch,Nuxt 的钩子函数 fetch 运行在 Vue 的 create 钩子函数之后,正如我们所知,所有的 Vue 生命周期钩子函数都是在他们对应的 this 上下文中被调用,fetch 也不例外。

此方法只能在组件中使用

    async fethch () {
      const res = await axios({
        method: 'GET',
        url: '/pc/story/index'
      })
        this.list = res,
    },
    data () {
        return {
          list: [],
        }
    }
  • 在服务端禁用 fetch

如果你需要的话,可以很方便的在服务端禁用 fetch 函数。

export default {
  fetchOnServer: false
};

中间件

使用中间件对用户进行身份验证,并允许他们在验证通过后访问页面

//校验某个页面是否登录
export default function ({ app, redirect }) {
    if (!app.$cookies.get('token')) {
        return redirect('/user/login.html')
    }
}

vue-awesome-swiper使用

  • 安装
npm install swiper vue-awesome-swiper --save
  • plugins/vue-awesome-swiper.js
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
Vue.use(VueAwesomeSwiper)
  • nuxt.config.js
css: [
        '@/node_modules/swiper/css/swiper.min.css',
    ],

plugins: [
        { src: "@/plugins/vue-awesome-swiper", ssr: false },
    ],
  • 使用

详见https://www.npmjs.com/package/vue-awesome-swiper

animate.css使用

  • 安装
npm install animate.css --save
  • nuxt.config.js
  css: [
        '@/assets/css/animate.css'
    ],
  • 在页面中使用

详见https://animate.style/

<h1 class="animate__animated animate__bounce">An animated element</h1>

wowjs使用

  • 安装
npm install wowjs --save-dev
  • 在mounted的生命周期中初始化WOW
if (process.browser) {
    // 在这里根据环境引入wow.js
    var { WOW } = require("wowjs");
}
mounted() {
    var wow = new WOW({
      live: false
    })
    wow.init()
}
  • 在页面中使用

详见https://blog.csdn.net/cs_dn_Jie/article/details/112374251

<div class="wow fadeInUp" data-wow-delay="50ms">fadeInUp动画效果</div>

vue-lazyload图片预加载

  • 安装
cnpm install vue-lazyload --save-dev
  • nuxt-config.js
import Vue from 'vue'
import VueLazyLoad from 'vue-lazyload'

Vue.use(VueLazyLoad, {
  preLoad: 2.3, //预加载高度比例
  error: "", //错误时加载图片
  loading: 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==', //预加载图片
  attempt: 2, //尝试加载图片数量
  throttleWait: 500 // 截流等待
})

  • nuxt.config.js
plugins: [
    { src: "@/plugins/vue-lazyload", ssr: false }
],
  • 页面中使用
<img v-lazy="baseUrl+item.pictor" :alt="" :title="" class="" />。
 类似资料: