Vue2-生命周期

news2025/7/11 16:27:48

之前说完了Vue的基础知识,说了语法、数据代理、数据监听、计算属性、指令、过滤器等等,但是没有涉及到Vue的声明周期,其实之所以把生命周期放在后面讲,是因为,如果最开始讲生命周期,里面涉及到的概念性东西比较多,初学者不容易理解,只能死记硬背。但是在理解了前面的这些基础知识之后,回过头来理解生命周期,就会很方便了。

源起 new Vue()

当我们通过 new Vue(),实例化一个Vue对象之后,就正式开启了 Vue 的旅程,这个对象内部包含了 Vue 对于数据的代理与监听、过滤器与指令的实现、计算属性与方法的编译等等一系列 Vue 提供的Api,以及我们即将详细说明的 生命周期,下面我们通过一个小例子来引出 Vue 的生命周期。

 这个例子就是一个渐变的过程,通过 Vue 来实现,现在我们不知道 Vue 的声明周期,然后结合我们之前 使用的方法,我们可以这么来做

<div id='root'>
  <h2 :style='{opacity}'>欢迎学习 Vue </h2>
</div>

<script>
  Vue.config.productionTip = false

  const vm = new Vue({
    el: '#root',
    data() {
      return {
        opacity: 1
      }
    },
  })

  setInterval(() => {
    if (vm.opacity <= 0) {
      vm.opacity = 1
    } else {
      vm.opacity -= 0.1
    }
  }, 100)
</script>

1、通过 绑定在data 内部的 opacity 属性,来控制 页面层透明度展示

2、通过定时器来循环控制透明度变化,

但是需要注意的是,因为我们此时没有用到生命周期,所以我们的定时器是不能写在 new Vue() 内部的配置项中的。例如下面的写法就是错误的

const vm = new Vue({
  el: '#root',
  data() {
    return {
      opacity: 1
    }
  },
  // 错误写法1: new Vue 内部传递一个对象,单独写一个定时器语法错误
  setInterval(() => {}),

  // 错误写法2:即使按照语法写了一个对象,但是 Vue 是不认识这个玩意的,打印 vm看一下就知道了
  a: setInterval(() => {}),
})

这么一看就会觉得很奇怪啊,我都是操作 data 内部的数据了,为啥还非要在外面 接收了 vm 实例,然后再来通过 vm 实例来操作 data 内部的属性,这不是多此一举么,难道不能直接在  new Vue ({}) 通过配置来实现这个操作么?答案当然是可以的,不然后面的组件化就没法进行了。

在 new Vue 内部配置

之前改变状态是写在外部的,这样不合理,所以我们把它配置在内部,之前讲到过 methods 属性,用来配置 某些方法,这里我们也这样写,这里的vm改成this就可以了,因为是在 new Vue() 内部取值的。

那么问题又来了,定义了方法,那我要怎么使用呢?当然,你可以加一个按钮,通过 @click事件来触发这个方法,但是我需要的是页面在初始化的时候,就调用这个方法,那咋办呢?

按照之前的插值语法或许可以这样?

<div id='root'>
  <h2 :style='{opacity}'>欢迎学习 Vue </h2>
  {{change()}}
</div>

直接在 页面上通过插值语法来调用这个方法,当解析到这一行代码时,发现插值语法,然后解析语法发现调用了这个方法,执行这个方法之后,发现没有返回值,没有返回值默认返回undefined,而undefined默认不展示在页面上,这样不就可以达到目的了么。确实,这样是可以实现的,但是存在问题,

 我们发现,页面变换已经变得很诡异了,并不是我们需要的效果,而且控制台上的输出已经成指数级增长了,这是因为,当页面第一次解析了插值语法之后,然后执行了 change 方法,此时 opacity 属性改变,然后页面重载,再次解析到了插值语法,重新执行change方法,再次改变 opacity属性,循环往复,每解析一次就开启一个定时器,然后就造成了这个效果

mounted :Vue完成模板解析,将初始生成的虚拟DOM转化为真实DOM,挂载到页面上后调用

1、mounted:和 methods 同级,是一个生命周期钩子函数

2、 mounted 内部的代码只执行一次,就是在 初始化 的时候,如果后续状态变化了,那叫更新

3、在 mounted 内部,如果需要使用 new Vue() 中的数据或方法,也是直接使用 this 指向

const vm = new Vue({
  el: '#root',
  data() {
    return {
      opacity: 1
    }
  },
  methods: {
    change() {
      console.log('开启了一个定时器')
      setInterval(() => {
        this.opacity -= 0.1
        if (this.opacity <= 0) this.opacity = 1
      }, 100)
    }
  },
  mounted() {
    // 也可以直接把 change 函数中的定时器 挪到 mounted 中,这只是我的个人习惯
    this.change()
  },
})

在这里就引出了 Vue 的生命周期钩子函数中的挂载之后调用的函数 mounted 生命周期钩子函数

Vue2生命周期 

这就是 Vue2 官网上的生命周期图,在这里 对每个生命周期以及每个模块都标注了tips,可以根据这些图例来辅助理解Vue的生命周期。

首先需要明白的是,这张图上面并不全部都是生命周期,真正的生命周期钩子函数只有8个,就是用红框单独框住的。其他的是 Vue 实例化过程中的流程。

1、生命周期:beforeCreate(创建前)

        1、beforeCreate(创建前)流程Vue实例创建之前 其实应该是说在数据代理和数据监听之前 先初始化生命周期,将生命周期定义在 Vue 实例中(生命周期函数有多少个,都叫啥,什么时候调用这些生命周期),然后接着 Vue 内部自带的事件修饰符(例如:once)定义,告诉 Vue 解析到了这些事件需要怎么处理。但是此时 Vue 中传入的 data 数据还未被代理,此时 vm 实例还未接收到 data 数据,也就不用说 vm_data 了。

        2、beforeCreate(创建前):此时无法在 new Vue() 内部通过this,或者在 外部通过 vm 访问到 data 中的数据,和 methods 中的方法 

2、生命周期:created(创建后)

       1、created(创建后)流程:在这个流程中,将传入的 data 数据进行数据代理 (挂载到vm实例上的data属性和方法)和 数据监测(对象监听  和 数组监听 _data 中的由get 和 set 转化过的data)  对象监测 

        2、created(创建后):此时能够在通过 this 或 vm 实例访问到 data 中的数据以及 methods中的方法

3、生命周期:beforeMount(载入前)

        1、beforeMount(载入前)流程这里的流程比较复杂,经过了两次判断,从而走了不同的流程,下面详细解析一下

                a、首先问你在 new Vue() 的时候,有没有传入 el 属性,一般我们是会传的,例如上面的例子传的就是 root。如果传了,那就直接走下面的流程,如果没传,我们可以在 vm 实例创建完成之后,通过 vm.$mount(el) 操作来实现相同的效果

new Vue({
  // 配置项 & 生命周期
}).$mount('#root')

                b、然后问你有没有 传入 templete 配置项,根据是否传入 来判断走哪一个流程 ,

                        (1)、如果没传,那就将 传入的 el 属性的 outerHtml 作为模板来编译( 之所以是 outerHTML 而不是 innerHTML 是因为,root所在的div 标签也是需要被编译进去的,可以在 root 所在的标签上 添加一个绑定属性来鉴定,因为如果改标签被编译了,那么绑定的属性也会编译)。

                        (2)、如果传了,那就是通过 render 函数,将 templete 配置项中的模板进行编译。templete 配置项其实就是一个字符串,直接将需要展示的页面复制粘贴进去就行,但是会发现语法报错,所以需要使用es6字符串模板。

el: '#root',
template: `<h2 :style='{opacity}'>欢迎学习 Vue </h2><h3>111111</h3>`,

现在语法不报错了,但是在编译过程中会出现一个错误

这个错误实际上说的就是,这个模板里面有两个根节点,解决办法就是在模板外部添加一个根节点进行包裹。

el: '#root',
template: `<div><h2 :style='{opacity}'>欢迎学习 Vue </h2><h3>111111</h3></div>`,

编译完成之后,我们可以在DOM节点中看到, templete 中的模板完全替代了 我们的el节点

                c、在这个编译解析过程中,此阶段 Vue 开始解析模板,生成的虚拟DOM还存在内存中,因为虚拟DOM此时还未转化为真实DOM,页面暂时还不能展示解析好的内容。展示的是未经编译的代码。

        2、beforeMount(载入前):此时页面呈现的是未经 Vue编译的 DOM 结构,所有对 DOM 的操作,最终都是不奏效的(因为下一步的操作直接将原来就生成的虚拟DOM生成了真实DOM,即使在这里改变了 DOM 结构,但是初始化的虚拟DOM还是为改变的,所以不奏效)。

4、mounted(载入后)

         1、mounted(载入后)流程:将内存中的虚拟DOM转化为真实DOM,然后创建一个vm实例下的 $el 属性,将真实DOM往 vm.$el 上存了一份,作为后期更新数据之后的复用节点对比。然后用 vm.$el 属性替代原本的 el 属性。在这个流程中,会插入页面中,此时页面展示的是经过编译之后的结果

        2、mounted(载入后):

                a、此时页面中呈现的是经过 Vue 编译过后的DOM。

                b、在这个生命周期中,对DOM的操作均是有效的(但尽可能避免在此阶段操作DOM)

                c、自此生命周期钩子函数执行完毕,代表初始化过程结束,一般在此进行:开启定时器,发送网络请求、订阅消息、绑定自定义事件等初始化操作

5、beforeUpdate(更新前)

        1、beforeUpdate(更新前)流程:这个流程没有做啥操作

        2、beforeUpdate(更新前):通过Vue的数据监听发现了数据更改之后,然后同步更新data中的数据,但是此时数据是新的,页面却还未改变,即:页面尚未与数据保持同步。

6、updated(更新后)

        1、updated(更新后)流程:数据更新之后根据新的数据生成新的虚拟DOM,随后与旧的虚拟DOM进行比较,然后生成新的真实DOM(此时会复用$el中保存的真实DOM),然后完成页面的更新。

        2、updated(更新后):此时数据是新的,页面也是新的,即:页面与数据已经保持同步。

7、beforeDestroy(销毁前)

        1、beforeDestroy(销毁前)流程:如果此时我不希望在我的数据更新之后,页面上继续响应变化,那么可以调用 vm.$destroy() 这个方法(这是有直接触发)或者等待路由切换等被动触发,那么 Vue 就进入了销毁流程

        2、beforeDestroy(销毁前):此时vm中的所有:data、methods、指令等等都还是处于可用状态,也就是说,之前的页面数据还是照常展示(能取到data中的数据),还可以点击按钮触发绑定的事件(但是事件触发后改变的data不会继续更新),马上进入销毁流程,一般在此阶段我们可以关闭定时器、取消订阅信息、解绑自定义事件等等操作。

8、destroyed(销毁后)

        1、destroyed(销毁后)流程:移除watcher监听器、子组件以及事件监听。

        2 、destroyed(销毁后):销毁整个vm 实例

但是在 Vue 调用这些生命周期钩子函数之前,存在一些流程,这些流程不是我们能够干预的,是 Vue 自己走完这些流程之后,自动执行了生命周期钩子函数,进而完成了 对 Vue 实例的完善

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/407581.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue路径component使用import的方式来写 component: () => import(‘@/views/order/orderDetail‘)

以前老师教的一直是这种写法: 工作后突然看到这种写法,我蒙了 首先我们先来理解一下,路由文件里面. path里面其实就是url也就是我们写路径的,我们在网址栏所看到的. 而component则是我们所对应的页面组件.每个页面相当于一个组件.所以我们的页面的名字就是组件的名字. 方法一:普…

掌握Mock摆脱后端同学的束缚

文章目录前言Mock概述mock.js安装Mock规范Mock的使用总结前言 当下采用前后端分离模式开发Web应用已经成为气候&#xff0c;在开发阶段有一个不成文的规定则是 项目开发后端先行 但是作为前端开发工程师的我们&#xff0c;难道在搭建完页面后只能等待后端的接口么&#xff1f;…

自定义修改el-talbe show-overflow-tooltip的样式

el-table表格行有一个可使用的show-overflow-tooltip属性&#xff0c;它接受一个Boolean&#xff0c;为true时多余的内容会在 hover 时以 tooltip 的形式显示出来。 <el-table-columnprop"address"label"地址"show-overflow-tooltip></el-table-…

Vue3、Vue2都有哪些区别

vue3和vue2版本对比&#xff1a; vue2中绝大多数的API与特性&#xff0c;在vue3中同样支持。同时&#xff0c;vue3中还新增了所特有的功能&#xff0c;并废弃了vue2中的某些旧功能。 新增的功能如&#xff1a;组合式API、多根节点组件、更好的TypeScript支持等。 废弃的功能…

jq获取和设置标签的css样式、jq给标签增加或移除class属性

1、jQuery获取和设置标签的css样式 jQuery既可以直接获取标签的css样式&#xff0c;也可以设置样式&#xff0c;包括行内、内部、外部样式&#xff1b;思路&#xff1a;先要选取这个标签&#xff0c;然后再获取或者设置样式&#xff1b;获取css属性&#xff1a;console.log($…

eclipse新建一个简单的网站(web)项目

目录前言一、新建一个简单web项目二、报错解决前言 本篇介绍怎么在eclipse中新建一个简单的web项目&#xff0c;博主是用的eclipse版本是2021-06R&#xff0c;服务器tomcat10。本篇是博主尝试自己动手搭建网站系列文章中的一篇&#xff0c;如想了解更多相关内容&#xff0c;见…

在web页面中直接播放rtsp视频流

rtsp是一种实时传输协议&#xff0c;通过各种百度了解&#xff0c;得出结论&#xff1a;浏览器是不支持播放rtsp流的&#xff0c;必须经过后端转码推流。 实现思路&#xff1a;借助node搭建转码推流服务&#xff0c;再使用JSMpeg播放。 rtsp2web是一个依赖 ffmpeg&#xff0c…

Vue页面生成PDF的方法

最近项目有个需求&#xff0c;将系统统计的数据生成分析报告&#xff0c;然后可以导出成PDF。 这种方法可以有两种&#xff0c;一种是直接调用打印&#xff0c;用户通过浏览器提供的打印页面手动选择导出PDF。当然这种方式兼容性差&#xff0c;且体验不好&#xff0c;显然不是…

net::ERR_CONNECTION_REFUSED 解决大全

sockjs-node/info报错 GET http://localhost/sockjs-node/info?t1641268443660 net::ERR_CONNECTION_REFUSED sockjs-node作用 SockJS is a JavaScript library (for browsers) that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascr…

前端页面出现 Failed to load response data

工作上前端 搭建了一套新的环境 同一个接口 新的前端环境 调用接口时 偶尔会出现一个情况 这时候 我们 在服务器 、 Postman 、本地环境调用都没问题 唯独在新的前端页面上会出现这样的问题 鉴于这样的问题 在网上查询了很多方法 进行修正都无济于事 最终在我们将问题指向了…

Android基础入门

第1章 Android基础入门 目录第1章 Android基础入门1.1 Android简介1.1.1 通信技术1.1.2 Android发展史1.1.3 Android体系结构1.1.4 Dalvik虚拟机1.2 Android开发环境搭建1.2.1 Android Studio安装1.2.2 模拟器创建1.2.3 SDK下载1.3 Android程序结构1.4 资源的管理与使用1.4.1 图…

前端第二章:9.HTML如何在网页中添加图片(img标签使用方法,以及img标签属性:alt、height、width);图片格式选择

一、img 标签简介 1.是自结束标签 2.用于向当前页面引入一个 外部图片 3.可以引入 gif 动图 4.img 是 替换元素&#xff0c;具有块元素和行内元素的某些特点 二、img标签基础 0.使用img标签将 图片 引入 网页&#xff01; 1.代码&#xff1a; <img src"图片的相对路…

【前端项目问题】Vue 中 v-html 的使用

Vue 中 v-html 的使用一、 v-html是什么&#xff1f;二、使用方式一、 v-html是什么&#xff1f; v-html 用来更新元素的 innerHTML&#xff0c;但是存在一定的安全性。 注意&#xff1a; 1、内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。 2、在网站上动态渲染任意 HTM…

前端技术发展历程

&#x1f482; 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 随着互联网的不断发展…

了解SVG-icon的使用流程

一.了解SVG是什么 SVG&#xff08;Scalable Vector Graphics&#xff09;可缩放矢量图形&#xff0c;是一种用于描述基于二维的矢量图形的 XML 标记语言&#xff0c;其基本矢量显示对象包括矩形、圆、椭圆、多边形、直线、任意曲线等&#xff0c;还能显示文字对象和嵌入式外部…

使用elementUI组件实现表格的分页以及搜索功能

主要的UI组件&#xff1a;el-input、el-table、el-pagination 效果展示&#xff1a; 主要功能&#xff1a; ① 完成列表与分页组件的联动&#xff0c;可以通过分页来实现列表数据翻页。 ② 通过在搜索栏输入关键词&#xff0c;在列表中展示出与关键词有关数据。 基础设置&a…

微信小程序实现滑动/点击切换Tab

背景 &#x1f44f; swiperscroll-view实现滑动/点击切换Tab&#xff0c;以及scroll-left的使用~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 2.1 scroll-view实现tab列表 scroll-view&#xff1a; 可滚动视图区域。使用竖向滚动时…

jsPDF + html2canvas A4分页截断 完美解决方案(含代码 + 案例)

业务需求 网页html生成A4大小分页的pdf&#xff0c;翻遍了整个互联网发现没有很系统的整理与分析&#xff0c;甚至对jsPDF的解析也没有几篇。遇到过几次&#xff0c;用的比较多&#xff0c;完成代码编写后特此整理分析&#xff0c;自我记录。 业务难点 1.存在图片/组件/文字…

vue弹窗如何嵌入其它vue页面

文章目录说明子组件&#xff0c;将要引入到弹框内的页面父页面思考组件 v-if 和 v-show 切换时生命周期钩子的执行说明 【1】实现方式&#xff0c;将其他页面作为组件传入 【2】在父页面&#xff0c;将该组件引入到弹框内&#xff0c;并通过动态渲染进行切换 子组件&#xff0…

使用宝塔面板快速搭建web网站,并内网穿透实现公网远程访问

目录 1. 环境安装 2. 安装cpolar内网穿透 3. 内网穿透 4. 固定http地址 5. 配置二级子域名 6. 创建一个测试页面 宝塔面板简单几步搭建本地web站点&#xff0c;并做内网穿透&#xff0c;实现公网用户也可以正常远程访问&#xff0c;无需公网IP&#xff0c;无需设置路由器…