Skip to content

nuxt常用知识点汇总

基本概念

中间件: 在一个页面渲染前执行

插件: 运行之前执行js脚本, 注入全局工具函数、配置信息等

模块: 扩展与封装Nuxt功能的模块【官方 模块

context

context 存在于"validate" 、asyncData"、"plugins"、"middlewares"、"modules" 和 "store/nuxtServerInit" 等

context可用属性

app(Vue根实例)

route(Vue路由对象)、params(route.params的别名)、query(route.query的别名)

store(Vuex.store实例)

isServer&isClient(环境判断)【 全局使用process.server 或 process.client 】

req&res(请求头&响应头) 注意判断process.server, 客户端为undefined

redirect(用于路由重定向, 默认返回状态码302)

error(展示错误页面并传递params)

nuxtState(获取nuxt状态, layout、config、routePath、serverRendered等)

beforeNuxtRender(更改nuxt状态) 只能在服务端调用

$config(runtime config配置)

nuxtServerInit

渲染前填充Vuex.state 第一个参数为store、第二个为context

js
export const actions = {
  async nuxtServerInit({ commit }, { $api, $config, req }) {
    // console.log(req.headers.cookie) // 获取到cookie
    commit('setRuntimeEnv', $config.runtimeEnv)
  }
}

plugins 插件

运行之前执行js脚本, 注入全局配置. 使用inject注入后可在context、Vue实例、Vuex实例加$访问

js
// nuxt.config.js
module.exports = {
    plugins: [
        '@/plugins/apis.js',
        '@/plugins/common.js'
    ]
}
// /plugins/apis.js  api注入
import apiConfig from '~/utils/api-config'
export default function ({ app: { $axios } }, inject) {
  let apis = {}
  Object.keys(apiConfig).forEach((item) => {
    let curItem = apiConfig[item]
    apis[item] = function (params = {}) {
      if (curItem.method === 'get') params = { params }
      return $axios[curItem.method](curItem.url, params, { headers: curItem.headers || { } })
    }
  })
  inject('api', apis)
}

modules 模块

扩展与封装Nuxt功能的模块【官方模块&开发指南

js
// nuxt.config.js
module.exports = {
  modules: [
    '@nuxtjs/axios', // 向context、Vue实例、Vuex实例注入 $axios
  ]
}

middleWare 路由中间件

在一个页面渲染前执行. global -> layout -> page

js
// middleware/auth.js
export default function (ctx) {
  console.log('auth middleware') // 例如用于校验token是否过期
}

// global 全局中间件,每个路由都会走进来一次
// nuxt.config.js
module.exports = {
  router: {
    middleware: ['auth']
  }
}

// layout/default.vue 布局中间件
export default {
  name: 'Default',
  middleware: ['auth']
}

// page/index.vue 页面中间件
export default {
  name: 'Index',
  middleware: ['auth']
}

serverMiddleware 服务中间件

  1. nuxt提供的API,启用后会在其内部创建connect instance.可用于编辑后端逻辑.
  1. 在vue-server-renderer之前执行且不会通过nuxt服务.
js
// nuxt.config.js
module.exports = {
  serverMiddleware: [
    '~/serverMiddleware/test'
  ]
}
// /serverMiddleware/test.js
export default {
  path: '/test',
  handler(req, res, next) {
    // console.log(require('connect'))
    res.end('Everything ok!')
  }
}

组件内更新对象

执行顺序: middleware => validate => asyncData => fetch => head

middleware

  1. String || Array || Function. 前端路由切换(nuxt-link)时在asyncData前执行
  1. 使用行为应与asyncData保持一致,即在pages下组件内调用

validate

  1. 验证动态路由参数是否合法. 必须return true才能正确往下渲染. return false会被重定向到error页
  1. 在asyncData前执行,使用行为应与asyncData保持一致,即在pages下组件内调用

asyncData

  1. 返回值为Promise时会等待resolve完成才会继续往下执行, 返回reject时如果没有catch会报错
  1. 该方法只注册在pages下面的vue组件, 即不支持components与layouts下的组件(写了没反应), 想让该类组件支持服务端渲染只能通过props传递.【注意: 即使是pages下的vue组件, 当成子组件使用时,asyncData也不会触发】
  1. 只有首屏在服务端渲染,前端路由切换(nuxt-link)时会beforeCreate钩子前调用. Vue的钩子beforeCreate 和 created会在客户端和服务端被调用, 其他生命周期函数仅在客户端被调用
  1. 无论在server还是在client端, 此钩子中的this为undefined

fetch

  1. 只有首屏在服务端渲染,前端路由切换(nuxt-link)时会在 beforeMount 钩子后 mounted 钩子前调用. 无论在服务端还是客户端都能获取到context中的store对象(即在客户端页可以更改Vuex的state)
  1. 使用行为应与asyncData保持一致,即在pages下组件内调用

Object || Function. 如果是函数可以使用this获取data数据

key

会应用到router-view的属性中,避免同一路由相同组件服用时导致不能重新渲染的问题

layout

设置布局组件,默认为default。布局组件应添加<nuxt />坑位

scrollToTop

控制当前页的滚动行为

transition

当前页面的动画切换控制

watchQuery

  1. Boolean || Array. 默认false. 为数组时可指定需要监听的query
  1. 监听url的query变化,重新执行asyncData, fetch, validate, layout等. 触发后,这些函数一般在客户端执行

Nuxt完整生命周期

Start => Nuxt hooks => serverMiddleware => plugins => nuxtServerInit => Middleware(global->layout->page) => asyncData=> beforeCreate => created => fetch => HTML rendering

常用功能项

全局css配置

loading配置

运行时全局变量注入

serverMiddleware服务端渲染中间件

默认html模板配置

自定义布局layout

坑: 完整匹配layouts目录下组件名称, 大小写敏感.

Nuxt给vue组件注入的方法

页面组件扩展方法一览: asyncData、fetch、validate、head、layout、loading、transition、scrollToTop、middleware

Vuex模块化

静态资源引入处理

全局变量注入

内置组件 nuxt的key值定义nuxt-child缓存(keep-alive)nuxt-link预加载(prefetch)

其他

nuxt.config.js

  • components: true // 自动注册components下的组件为全局组件

$nuxt

Nuxt.js提供的客户端window/Vue组件对象( 通过window.$nuxt或this.$nuxt访问)

  • $nuxt.refresh()刷新asyncData或fetch而不刷新页面
  • $nuxt.$loading()控制加顶部载条

常用构建配置

nuxt.config.js

端口配置

js
server: {
    port: 8000,
    host: 'localhost',
    disableHostCheck: true
}

禁止数据收集

js
telemetry: false

全局变量注入

nuxt start会同时注入context、Vue实例、Vuex.store实例的运行时环境变量(服务端&客户端均可读). 通过context.$config.xxx访问

也可配置env使用,但是在docker集群中无效. env配置方法

js
publicRuntimeConfig: {
    runtimeEnv: process.env.CUR_ENV
}
// 服务端访问
asyncData(ctx) {
    console.log(ctx.$config.runtimeEnv)
}
// 客户端访问
mounted(ctx) {
    console.log(this.$config.runtimeEnv)
}
// Vuex访问
export const actions = {
    async nuxtServerInit({ commit }, { $api, $config, req }) {
        console.log(this.$config.runtimeEnv)
    }
}

代理配置

js
modules: [
    '@nuxtjs/axios', // 注入 $axios Doc: https://axios.nuxtjs.org/usage
],
axios: {
    proxy: true, // 启动代理转发
    proxyHeaders: true // 转发请求头部信息, 默认true
},
proxy: [
    ["/v1/", {target: 'http://localhost:3000' }]
]

全局头部

js
head: {
    title: '页面标题',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'description' }
    ],
    link: [
      // 应用启动后static目录下的文件会映射至应用的根路径 / 下
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      { rel: 'stylesheet', href: '/animate.min.css' }
    ]
}

顶部loading条

js
loading: { color: '#E90300' },
<!--可自定义配置组件-->
// loading: '~/components/loadingTab.vue',

全局css & scss变量混入

js
modules: [
    "@nuxtjs/style-resources", // 全局scss注入的插件
],
css: [
    './assets/style/reset.css',
    // 巨坑:在styleResources.scss引入global.scss会加入作用域,导致不能全局生效
    './assets/style/scss/global.scss',
],
styleResources: {
    scss: [
      './assets/style/scss/variable.scss', // 优先引入scss变量, 下面俩个才能引用
      './assets/style/scss/element-variable.scss',
      './assets/style/scss/mixins.scss',
    ]
}

vue-router扩展

js
router: {
    middleware: ['auth'],
    extendRoutes(routes) {
      // params&props解耦操作
      const appendPassProps = function(rs) {
        for (const route of rs) {
          route.props = /:/.test(route.path)
          if (route.children) {
            appendPassProps(route.children)
          }
        }
      }
      appendPassProps(routes)
      return routes
    },
    // 页面跳转滚动条配置
    scrollBehavior(to, from, savedPosition) {
      // 前进后退保持滚动条位置不变
      if (savedPosition) { return savedPosition }
      // 路由跳转滚动顶部
      return { x: 0, y: 0 }
    }
}

build构建配置

js
build: {
    transpile: [/^element-ui/], // node_modules下需要使用babel转译的库
    parallel: true, // 多进程打包(提升构建速度)
    cache: true, // 构建文件缓存(提升构建速度)
    extractCSS: CUR_ENV !== 'local' // 提取内联css到单独文件【与parallel多进程冲突,开发时需关闭】
}