-
Vue 生命周期方法详解
-
beforeCreate
- 执行时机:在实例初始化之后,数据观测(data observer)和事件配置(event/watcher setup)之前被调用。
- 内部状态:此时,组件的选项对象(例如
data
、methods
、computed
等)已经可以访问,但是这些数据还没有进行响应式处理。这意味着this
指向组件实例本身,不过如果尝试访问data
中的数据或者methods
中的方法,是无法获取到预期结果的。例如,在beforeCreate
钩子函数中访问this.message
(假设message
是data
中的一个属性),会得到undefined
,因为数据还没有被代理,不能进行响应式的访问。 - 应用场景:这个阶段很少用于业务逻辑,因为大多数操作都依赖于响应式数据或者已经初始化好的方法。不过,它可以用于记录一些初始的日志或者进行一些与组件实例创建相关的调试工作。
-
created
- 执行时机:在实例完成数据观测和事件配置后被调用。
- 内部状态:此时,
data
中的数据和methods
中的方法都已经可以正常访问和使用,它们已经经过了响应式处理。这意味着可以在这个阶段安全地调用组件的方法,并且可以对data
中的数据进行操作。但是,此时组件还没有挂载到 DOM 上,所以如果尝试访问el
属性或者操作 DOM 元素(如document.getElementById
等),是不会得到预期的挂载后的 DOM 元素的。 - 应用场景:
- 数据初始化:可以在这里初始化一些数据,特别是那些不需要依赖 DOM 的情况。例如,对
data
中的某些属性进行初始计算或者赋值。 - 异步请求数据:这是一个非常适合发送异步请求获取数据的阶段。因为组件已经完成初始化,并且在请求返回后,可以很方便地将数据赋值给
data
中的属性,从而触发视图的更新。由于数据的更新是响应式的,一旦数据赋值成功,Vue 会自动更新与这些数据绑定的 DOM 元素。例如,在一个用户管理组件中,可以在created
阶段发送请求获取用户列表数据,然后将数据存储在data
中的一个数组属性中,用于后续在模板中渲染用户列表。
- 数据初始化:可以在这里初始化一些数据,特别是那些不需要依赖 DOM 的情况。例如,对
-
beforeMount
- 执行时机:在模板编译完成后,即将把模板渲染到真实 DOM 之前调用。
- 内部状态:
el
属性所指向的挂载点已经存在,但是虚拟 DOM(Virtual DOM)还没有生成真实的 DOM 元素来替换挂载点的内容。此时可以获取到模板编译后的虚拟 DOM 结构,但它还没有真正应用到页面上。 - 应用场景:这个阶段可以用于在 DOM 渲染之前进行最后的准备工作。例如,对模板中的某些指令或者属性进行最后的检查或者修改,不过这种情况比较少见。通常情况下,大多数操作可以在
mounted
阶段或者created
阶段完成。
-
mounted
- 执行时机:在组件挂载到真实 DOM 后调用。
- 内部状态:此时,组件已经成功渲染到页面上,
el
属性指向的挂载点已经被真实的 DOM 元素替换,并且可以通过this.$el
来访问组件的根 DOM 元素。可以使用 JavaScript 的原生 DOM 操作方法或者其他第三方 DOM 库(如jQuery
)来与 DOM 进行交互。 - 应用场景:
- DOM 操作:如果需要获取 DOM 元素的尺寸、位置等信息,或者对 DOM 元素进行复杂的样式修改、添加事件监听器等操作,这个阶段是最合适的。例如,在一个图片懒加载组件中,需要在图片加载完成后,获取图片的实际尺寸来调整布局,那么可以在
mounted
阶段进行相关操作。 - 初始化第三方插件:对于一些需要 DOM 元素存在才能正确初始化的第三方插件,如某些图表库、富文本编辑器等,应该在
mounted
阶段进行初始化。例如,在一个使用echarts
绘制图表的组件中,需要在mounted
阶段获取 DOM 元素作为容器,然后初始化echarts
实例并传入数据进行图表绘制。 - 发送请求(与 DOM 相关的数据):如果请求的数据需要与 DOM 元素进行交互,比如根据请求返回的数据动态地创建 DOM 元素或者更新已有的 DOM 元素的内容,那么在
mounted
阶段发送请求是一个不错的选择。这样可以确保 DOM 已经存在,方便后续的数据更新操作。
- DOM 操作:如果需要获取 DOM 元素的尺寸、位置等信息,或者对 DOM 元素进行复杂的样式修改、添加事件监听器等操作,这个阶段是最合适的。例如,在一个图片懒加载组件中,需要在图片加载完成后,获取图片的实际尺寸来调整布局,那么可以在
-
beforeUpdate
- 执行时机:当组件的数据发生变化,在虚拟 DOM 重新渲染和打补丁(patch)之前被调用。
- 内部状态:此时,组件的
data
已经更新,但是 DOM 还没有更新。可以通过比较新旧数据来确定哪些部分的数据发生了变化,从而进行一些在 DOM 更新之前的预处理操作。不过要注意,在这个阶段修改数据可能会导致无限循环的更新,因为数据的修改又会触发beforeUpdate
钩子函数的调用。 - 应用场景:
- 数据预处理:可以对即将更新的 DOM 相关的数据进行预处理。例如,在一个列表组件中,如果数据发生变化导致列表项的数量或者内容发生改变,可以在
beforeUpdate
阶段计算新的列表布局相关的数据,如每个列表项的高度、宽度等,以便在 DOM 更新后能够更快地进行布局调整。
- 数据预处理:可以对即将更新的 DOM 相关的数据进行预处理。例如,在一个列表组件中,如果数据发生变化导致列表项的数量或者内容发生改变,可以在
-
updated
- 执行时机:在组件的 DOM 根据数据变化更新完成后被调用。
- 内部状态:此时,DOM 已经更新完毕,与新的数据保持一致。可以在这个阶段对更新后的 DOM 进行检查或者操作,但是要注意,由于数据的任何微小变化都会导致这个钩子函数被调用,所以在这里进行的操作应该尽量简洁,避免性能问题。
- 应用场景:
- DOM 更新后的检查:可以检查 DOM 更新后的状态是否符合预期。例如,在一个表单组件中,数据更新可能会导致表单字段的显示状态或者验证状态发生变化,在
updated
阶段可以检查这些表单字段是否正确显示和验证。 - 与更新后的 DOM 交互:如果需要在 DOM 更新后进行一些动画效果或者其他与 DOM 相关的交互操作,如滚动到某个特定位置、显示更新后的提示信息等,可以在这个阶段进行。不过,要谨慎使用,避免因为频繁的数据变化而导致过多的操作。
- DOM 更新后的检查:可以检查 DOM 更新后的状态是否符合预期。例如,在一个表单组件中,数据更新可能会导致表单字段的显示状态或者验证状态发生变化,在
-
beforeDestroy
- 执行时机:在组件被销毁之前被调用。
- 内部状态:此时,组件仍然是完全可用的,
data
、methods
等仍然可以访问,DOM 元素也还存在。这是在组件销毁前进行清理工作的最后机会。 - 应用场景:
- 资源清理:清除组件中创建的定时器(
setTimeout
、setInterval
)、取消订阅的事件(如EventBus
中的事件订阅)、关闭 WebSockets 连接等。例如,如果在组件中创建了一个每隔一段时间就更新数据的定时器,在beforeDestroy
阶段需要清除这个定时器,以避免内存泄漏和不必要的资源消耗。 - 解绑自定义事件监听器:如果在组件中绑定了一些自定义的事件监听器,如在组件内部通过
addEventListener
绑定的 DOM 事件或者自定义的事件,需要在这个阶段进行解绑。
- 资源清理:清除组件中创建的定时器(
-
destroyed
- 执行时机:在组件被销毁后被调用。
- 内部状态:此时,组件实例的所有指令都已经被解绑,事件监听器被移除,
data
和methods
等也都不再可用。组件的 DOM 元素通常也已经从页面上移除(具体取决于组件的销毁方式和父组件的操作)。 - 应用场景:这个阶段主要用于一些最后的清理工作或者记录组件已经被销毁的日志。不过,由于组件已经完全销毁,大多数操作都应该在
beforeDestroy
阶段完成。
-
-
发送请求的位置及详细原因
-
created 阶段发送请求
- 详细原因:
- 组件初始化完成:在
created
阶段,组件已经完成了数据观测和事件系统的初始化,这意味着data
中的属性已经是响应式的。可以方便地使用this
来访问和操作数据属性,为发送请求提供了稳定的数据基础。例如,在请求中需要携带组件的某个data
属性作为参数时,可以直接使用this.propertyName
来获取。 - 数据更新响应式:当请求返回数据后,可以将数据赋值给
data
中的属性,由于数据是响应式的,Vue 会自动检测到数据的变化并更新与之绑定的 DOM 元素。这样可以确保视图能够及时地反映数据的变化,而不需要手动操作 DOM 来更新视图。例如,在一个新闻列表组件中,在created
阶段发送请求获取新闻列表数据,将数据赋值给data
中的newsList
属性后,模板中通过v - for
指令绑定newsList
的部分会自动更新,显示最新的新闻列表。 - 尽早获取数据:相比于
mounted
阶段,created
阶段更早执行。对于一些不需要等待 DOM 挂载就可以进行的数据处理和展示,在这个阶段获取数据可以提高应用的性能和用户体验。例如,对于一个只显示简单文本数据的数据展示组件,在created
阶段获取数据并更新视图,可以让用户更快地看到数据内容,减少等待时间。
- 组件初始化完成:在
- 示例场景拓展:
- 初始化配置数据:在一个具有多种配置选项的组件中,如一个地图组件,在
created
阶段可以发送请求获取地图的初始配置数据,如地图的类型(卫星图、平面图等)、初始缩放级别、中心点坐标等。这些数据获取后存储在data
属性中,用于后续地图的初始化和显示。 - 预加载关联数据:对于一个具有关联关系的数据组件,如一个文章详情组件和它的评论组件。在文章详情组件的
created
阶段,可以发送请求获取文章详情数据,同时预加载评论数据(即使评论部分可能在 DOM 上还没有显示)。这样当用户切换到评论部分时,可以更快地展示评论内容,减少用户等待时间。
- 初始化配置数据:在一个具有多种配置选项的组件中,如一个地图组件,在
- 详细原因:
-
mounted 阶段发送请求
- 详细原因:
- DOM 已挂载:在
mounted
阶段,组件已经成功挂载到 DOM 上,这意味着可以直接访问和操作 DOM 元素。如果请求的数据需要与 DOM 进行交互,如根据数据动态地创建 DOM 元素、更新 DOM 元素的样式或者属性等操作,在这个阶段发送请求是必要的。例如,在一个树形菜单组件中,需要获取菜单数据后根据数据动态地生成 DOM 结构来展示菜单,那么在mounted
阶段发送请求,在数据返回后就可以立即操作 DOM 来构建菜单。 - 第三方插件集成:对于一些需要 DOM 元素存在才能正确初始化的第三方插件,在
mounted
阶段发送请求获取插件所需的数据并进行初始化是最合适的。例如,在一个使用swiper
插件制作轮播图的组件中,需要在mounted
阶段发送请求获取轮播图的数据,然后在数据返回后,以 DOM 元素为容器初始化swiper
实例,将数据传递给swiper
进行轮播图的展示。 - 数据与 DOM 交互的优化:有时候,数据的展示需要根据 DOM 元素的实际情况进行优化。例如,在一个自适应布局的组件中,需要根据 DOM 元素的实际宽度和高度来请求合适的数据量或者数据格式。在
mounted
阶段发送请求,可以获取 DOM 元素的尺寸信息后,再发送更精准的请求,以达到更好的数据展示效果。
- DOM 已挂载:在
- 示例场景拓展:
- 动态图表绘制:在一个数据可视化组件中,如绘制柱状图。在
mounted
阶段发送请求获取图表数据,然后根据 DOM 元素的尺寸(通过this.$el
获取)来确定图表的大小和比例,进而绘制出合适的图表。如果在created
阶段发送请求,由于无法获取 DOM 元素的尺寸,可能会导致图表绘制后与 DOM 布局不协调的问题。 - 图片懒加载与占位符替换:在一个图片懒加载组件中,
mounted
阶段发送请求获取图片的真实路径(假设初始使用占位符图片)。当请求返回后,根据 DOM 元素(图片标签)的位置和尺寸,将占位符图片替换为真实的图片,并进行适当的加载动画等操作,以提供更好的用户体验。
- 动态图表绘制:在一个数据可视化组件中,如绘制柱状图。在
- 详细原因:
-