nuxt的生命周期——nuxt2
nuxt搭建的vue框架的生命周期分三部分来看:nuxt的生命周期、vue的生命周期、其他的生命周期。一个用于处理store数据的钩子,只会执行一次,一般用于操作store数据的初始化。不同页面间需要操作相同的数据请求的时候,只要数据发生变化,Render都会重新渲染。运行在请求发出后,页面初始化之前,所以一般在页面中使用validata钩子。一般写在store文件夹中,运行在服务端,输出在服务端
文章目录
生命周期划分
nuxt搭建的vue框架的生命周期分三部分来看:nuxt的生命周期、vue的生命周期、其他的生命周期
- nuxt生命周期在
服务端
,输出在服务端或浏览器端 - vue的
beforeCreated和created
钩子运行在在服务端
和客户端
,输出在服务端或浏览器端 - vue的其他的生命周期在
客户端
,输出在浏览器端
nuxt生命周期 钩子
- Nuxt的生命周期跑在
服务端
,但是他的输出即可能在服务端也可能在浏览器
。 - Nuxt生命周期的钩子一般都会接受一个上下文参数context,里面包含着服务端的多种数据信息:{isDev, route, store, env, params, query, req, res, redirect, error }等
生命周期图:
nuxtServerInit
一个用于处理store数据的钩子,只会执行一次,一般用于操作store数据的初始化。
一般写在store文件夹中,运行在服务端,输出在服务端和客户端。
store/index.js:
export const actions = {
/**
*
* @param {*} store store的实例对象
* @param {*} context 上下文(服务端所有的数据信息)
*/
nuxtServerInit(store, context) {
console.log("nuxtServerInit", store, context);
}
}
服务端输出:
同时浏览器输出:
服务端和浏览器都有输出,说明输出可能在服务端也可能在浏览器
,下面的几个Nuxt钩子有同样的状况。
middleware
中间件的钩子,可以自定义一些函数,可以运行在全局前,某个页面前,也可以运行在组件渲染前,需要在配置文件进行配置:
- nuxt.config.js 全局中间件的配置
- layouts 布局中间件的配置
- pages 页面中间件的配置
执行顺序:全局中间件 ==> 布局中间件 ==>页面中间件
中间件都会有一个包含服务端上下文信息
的参数context,可用可不用
- nuxt.config.js 全局中间件的配置
这里以路由中间件为例:
nuxt.config.js
export default {
// 服务端渲染模式,同构
mode: 'universal',
/*
** 页面Head
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
/**
* 路由中间件配置
*/
router: {
middleware:'auth'
},
/*
** loading样式
*/
loading: { color: '#fff' },
/*
** 全局样式
*/
css: [
],
/*
** 全局插件
*/
plugins: [
],
/*
** 开发模式的模块
*/
devModules: [
],
/*
** 模块
*/
modules: [
],
/*
** 打包配置
*/
build: {
/*
** You can extend webpack config here
*/
extend (config, ctx) {
}
}
}
文件的名字就是该中间件的名字:
middleware/auth.js:
/**
* 接收一个全局上下文参数context
*/
export default ({ store, route, redirect, param, query, req, res }) => {
// 全局守卫业务
console.log("router-middleware")
}
访问任何路径都会输出router-middleware
。
中间件的几个参数信息,这几个参数是存储在全局上下文参数context
中的:
- store: 状态树信息,vuex的相关信息
- route:目标路由的信息
- redirect:强制跳转
- param:param参数信息
- query:query参数信息
- req:请求的req信息
- res:响应的res信息
- layout 布局中间件的配置
layouts/default.vue
<template>
<div>
<nuxt />
</div>
</template>
<script>
export default {
// layout层级中间件
// 1. 引用外部中间件
middleware: 'auth',
// 2. 使用内部中间件
middleware() {
console.log('layout middleware')
}
}
</script>
- page页面中间件的配置
页面中间件运行在页面实例化之前
pages/index.vue
<template>
<div class="container">
</div>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
// 中间件
// 1. 引用外部中间件
middleware: 'auth',
// 2. 使用内部中间件
middleware() {
console.log('page middleware')
},
components: {
Logo
},
}
</script>
validate
校验客户端请求所携带的参数是否符合校验
,校验成功可以返回页面,否则返回404页面。
运行在请求发出后,页面初始化之前,所以一般在页面中使用validata钩子。
<template>
<div class="container">
</div>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
validate({ param, query }) {
// 校验业务
return true;//校验通过
},
components: {
Logo
},
}
</script>
asyncData & fetch
用于处理异步数据
- asyncData :渲染组件前获取异步数据数据
- fetch:也是在渲染组件前获取异步数据数据
一般在页面中使用这两个钩子,在页面渲染之前获取数据。
pages/index.vue
<template>
<div class="container">
<div>
<logo />
<h1 class="title">
SSR2.9
</h1>
</div>
</div>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
// 获取数据,返回给组件
asyncData() {
// 异步业务逻辑,读取服务端数据
// 返回结果和组件的目标数据(data(){})进行合并
console.log("asyncData");
return {
b:2
}
},
// 获取数据,返回给状态数(vuex)
fetch({store}){
// 异步业务逻辑,读取服务端数据交给vuex
console.log("asyncData");
},
components: {
Logo
},
data() {
return {
a:1
}
}
}
</script>
Render
服务端渲染,将渲染后的页面返回给客户端。
不同页面间需要操作相同的数据请求的时候,只要数据发生变化,Render都会重新渲染。
- render函数之定义渲染的配置,内部不要编写业务逻辑,即使写的也不执行
nuxt生命周期 和 vue生命周期钩子之间的运行顺序
nuxt生命周期钩子 ⇒ vue的beforeCreated和created钩子 ⇒ vue的其他生命周期钩子
钩子的参数信息
- 在服务器端运行的钩子都可以拿到服务器端的上下文信息,但是拿不到客户端的数据(如windows),不能访问this.
服务端的钩子运行客户端渲染前,自然拿不到客户端的数据信息 - 在客户端运行的vue钩子都可以拿到客户端的数据(如windows),不能拿到服务器端的上下文信息,可以访问this,代表的是组件实例自身。
- 既运行在服务端的钩子有运行在客户端的钩子(beforeCreate和create)可以拿到服务器端的上下文信息,但是拿不到客户端的数据(如windows),可以访问this,代表的是组件实例自身。
Nuxt SSR渲染的顺序
简单来说
服务端钩子子执行 ==> 服务渲染生成HTML(此时页面就已经可以展示给用户了,只是不能进行DOM操作) ==> 客户端钩子执行(Vue接管页面并进行客户端激活,为页面添加DOM操作)
可以查看VUE最原始的SSR实现进行理解:https://cn.vuejs.org/guide/scaling-up/ssr.html
具体来说
服务端渲染阶段:
- nuxtServerInit(如果存在):在 Vuex store 中定义,用于在服务端初始化 store。
- middleware(如果存在):在进入页面之前调用,用于中间件逻辑。
- validate(如果存在):在进入页面之前调用,用于验证路由参数。
- asyncData(如果存在):在组件实例化之前调用,用于异步获取数据。
- fetch(如果存在):在组件实例化之前调用,用于获取数据。
- serverPrefetch(如果存在):在组件实例化之前调用,用于在服务端预取数据。
- 服务端渲染组件树并生成 HTML。
- 将渲染好的 HTML 发送到客户端。
客户端激活阶段:
- 客户端接管并激活 Vue 组件。
- 执行客户端钩子函数(beforeCreate 和 created 会在服务端和客户端都执行)。
- beforeMount:在组件挂载到 DOM 之前调用。
- mounted:在组件挂载到 DOM 之后调用。
Fetch和mounted的执行顺序
- 正常情况下的执行顺序是:
Fetch(服务端执行,执行完才会生成HTML) ==> HTML ==> mounted(客户端执行)
,这种情况下可以确保mounted钩子是在Fetch钩子执行完之后才执行的。 - 有特殊性情况:当组件不是在页面初始渲染的时候就已经存在,那么SSR渲染的时候并不会执行该组件中的fetch函数,而是在客户端激活阶段或在组件实际渲染到页面时执行。那么执行顺序就是
HTML ==>Fetch(客户端执行) ==> mounted(客户端执行)
,执行顺序是fetch先执行mounted后执行,但是钩子函数是到什么时间节点触发什么钩子,所以mounted是不会等fetch执行完再执行。
具体参见:https://blog.csdn.net/mantou_riji/article/details/140550360
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)