云计算百科
云计算领域专业知识百科平台

Vue在created与mounted请求数据深度解析:掌握生命周期钩子的最佳实践

一、Vue生命周期钩子核心概念解析

1.1 Vue实例的生命周期概述

Vue实例从创建到销毁的过程就是生命周期。在这个过程中,Vue会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己代码的机会。理解生命周期的各个阶段,是掌握Vue进阶开发的必经之路。

1.2 created钩子的触发时机与特点

在实例创建完成后被立即调用。此时,实例已完成数据观测(data observer)、属性和方法的运算以及watch/event事件回调。然而,挂载阶段还未开始,$el属性目前不可见。这意味着在created阶段,我们可以访问到组件的数据和方法,但无法操作DOM节点。

1.3 mounted钩子的触发时机与特点

在挂载完成后调用,此时真实的DOM节点已经被渲染到页面上。如果需要对DOM进行操作,或者初始化某些依赖DOM的第三方库(如ECharts、Swiper等),mounted是最佳时机。此时可以通过this.$el访问到组件的根DOM元素。

二、created与mounted请求数据的核心区别

2.1 执行时机与DOM状态差异

在created中发请求,此时DOM还未挂载,请求与DOM的渲染是并行的。如果数据请求较快,DOM挂载时可能已经有数据了,直接渲染带数据的页面。而在mounted中发请求,必须等DOM挂载完成后才会发起,请求返回的数据通常会触发组件的重新渲染。

2.2 服务端渲染(SSR)的兼容性对比

在进行Vue服务端渲染(SSR)时,created钩子会在服务端和客户端都被执行,而mounted钩子只在客户端执行。因此,如果项目使用了SSR技术,且需要在首屏加载时获取数据,必须将数据请求放在created中,否则服务端将无法获取初始数据,导致首屏渲染为空。

2.3 用户体验与加载性能分析

从性能角度看,created中发起请求能更早地开始网络传输,理论上能更快地拿到数据。但这并不意味着绝对优于mounted。如果在created中请求的数据需要大量复杂的DOM操作,可能需要等待DOM挂载后才能执行,反而增加了代码复杂度。在mounted中请求虽然稍晚,但此时页面骨架已呈现,可以通过loading动画给用户更好的视觉反馈。

三、生命周期数据请求的流程与实战应用

3.1 生命周期数据请求流程图

通过Mermaid流程图,我们可以直观地看到Vue实例在created和mounted阶段请求数据的执行差异与流程走向。

#publish-mermaid-1785343176624-0{font-family:inherit;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-1785343176624-0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-1785343176624-0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-1785343176624-0 .error-icon{fill:#552222;}#publish-mermaid-1785343176624-0 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-1785343176624-0 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-1785343176624-0 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-1785343176624-0 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-1785343176624-0 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-1785343176624-0 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-1785343176624-0 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-1785343176624-0 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-1785343176624-0 .marker.cross{stroke:#333333;}#publish-mermaid-1785343176624-0 svg{font-family:inherit;font-size:16px;}#publish-mermaid-1785343176624-0 p{margin:0;}#publish-mermaid-1785343176624-0 .label{font-family:inherit;color:#333;}#publish-mermaid-1785343176624-0 .cluster-label text{fill:#333;}#publish-mermaid-1785343176624-0 .cluster-label span{color:#333;}#publish-mermaid-1785343176624-0 .cluster-label span p{background-color:transparent;}#publish-mermaid-1785343176624-0 .label text,#publish-mermaid-1785343176624-0 span{fill:#333;color:#333;}#publish-mermaid-1785343176624-0 .node rect,#publish-mermaid-1785343176624-0 .node circle,#publish-mermaid-1785343176624-0 .node ellipse,#publish-mermaid-1785343176624-0 .node polygon,#publish-mermaid-1785343176624-0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785343176624-0 .rough-node .label text,#publish-mermaid-1785343176624-0 .node .label text,#publish-mermaid-1785343176624-0 .image-shape .label,#publish-mermaid-1785343176624-0 .icon-shape .label{text-anchor:middle;}#publish-mermaid-1785343176624-0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-1785343176624-0 .rough-node .label,#publish-mermaid-1785343176624-0 .node .label,#publish-mermaid-1785343176624-0 .image-shape .label,#publish-mermaid-1785343176624-0 .icon-shape .label{text-align:center;}#publish-mermaid-1785343176624-0 .node.clickable{cursor:pointer;}#publish-mermaid-1785343176624-0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-1785343176624-0 .arrowheadPath{fill:#333333;}#publish-mermaid-1785343176624-0 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-1785343176624-0 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-1785343176624-0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785343176624-0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-1785343176624-0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785343176624-0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-1785343176624-0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-1785343176624-0 .cluster text{fill:#333;}#publish-mermaid-1785343176624-0 .cluster span{color:#333;}#publish-mermaid-1785343176624-0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:inherit;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-1785343176624-0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-1785343176624-0 rect.text{fill:none;stroke-width:0;}#publish-mermaid-1785343176624-0 .icon-shape,#publish-mermaid-1785343176624-0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785343176624-0 .icon-shape p,#publish-mermaid-1785343176624-0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-1785343176624-0 .icon-shape .label rect,#publish-mermaid-1785343176624-0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785343176624-0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-1785343176624-0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-1785343176624-0 .node .neo-node{stroke:#9370DB;}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].node rect,#publish-mermaid-1785343176624-0 [data-look=\”neo\”].cluster rect,#publish-mermaid-1785343176624-0 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785343176624-0 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785343176624-0 :root{–mermaid-font-family:inherit;}

Vue实例初始化

执行created钩子

是否在created发起请求?

发起HTTP请求

等待DOM挂载

等待DOM挂载

执行mounted钩子

是否在mounted发起请求?

发起HTTP请求

结束初始化

请求返回, 更新数据并重新渲染DOM

结束初始化

3.2 在created中请求数据的适用场景

  • 纯数据展示场景:获取的数据仅用于模板渲染,不涉及DOM操作。
  • SSR项目首屏渲染:需要在服务端获取数据并渲染HTML字符串。
  • 依赖尽早获取的全局配置:如获取用户权限、基础字典等,越早拿到越能避免后续逻辑出错。
  • 代码示例如下:

    export default {
    data() {
    return {
    userInfo: null
    }
    },
    created() {
    this.fetchUserInfo()
    },
    methods: {
    async fetchUserInfo() {
    const res = await api.getUser()
    this.userInfo = res.data
    }
    }
    }

    3.3 在mounted中请求数据的适用场景

  • 依赖DOM的图表渲染:获取数据后需要初始化ECharts或其他图表库。
  • 需要计算元素尺寸的请求:某些数据渲染依赖容器的宽高,必须等DOM挂载后。
  • 非首屏关键数据:如页面底部的推荐列表、评论等,可推迟到mounted获取。
  • 代码示例如下:

    export default {
    data() {
    return {
    chartData: []
    }
    },
    mounted() {
    this.fetchChartData()
    },
    methods: {
    async fetchChartData() {
    const res = await api.getChartData()
    this.chartData = res.data
    this.initChart()
    },
    initChart() {
    const chart = echarts.init(this.$refs.chartDom)
    chart.setOption({ series: [{ data: this.chartData }] })
    }
    }
    }

    四、最佳实践与常见问题总结

    4.1 数据请求时机的选择策略

  • 默认情况下,推荐在created中发起首屏关键数据的请求,以获得更快的首屏渲染速度。
  • 当请求的数据直接服务于DOM操作或第三方库初始化时,应将其放在mounted中。
  • 在组件内部路由跳转时,若需要复用组件,通常在activated或beforeRouteEnter中请求,但基础原则与生命周期一致。
  • 4.2 避免常见误区与代码规范

  • 避免在beforeCreate中请求数据,此时data和methods均未初始化,无法赋值或调用方法。
  • 不要在created中尝试通过this.$el或this.$refs操作DOM,这会导致报错。
  • 在SSR项目中,严禁在mounted中请求首屏数据,因为这会导致客户端水合(hydration)前后数据不一致。
  • 无论在哪个钩子中请求,都应处理好loading状态和错误捕获,保证用户体验与代码健壮性。
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » Vue在created与mounted请求数据深度解析:掌握生命周期钩子的最佳实践
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!