技术标签: vue vue.js javascript
vue是每一个前端开发人员都绕不过的一个技术,在国内的市场占有量也是非常的大,我们大部分人用着vue, 却不知道他内部其实经历了一些什么。每个生命周期又是什么时候开始执行的。我们今天来详细的看一看
首先,生命周期是个啥?
借用官网的一句话就是:每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。那么这些过程中,具体vue做了些啥,我们今天来了解一下。
了解之前,我们先贴上一张官网的生命周期图,从图上,我们再一步一步来理解vue生命周期。
我们先简单的来解说这张图,然后再通过例子来详看
首先,从图上,我们可以看出,他的一个过程是
大致过程就是这样,下面我们来通过例子来看一看
<body>
<div id="app">
<p>{
{
message}}</p>
<button @click="changeMsg">改变</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello world'
},
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
beforeCreate() {
console.log('------初始化前------')
console.log(this.message)
console.log(this.$el)
},
created () {
console.log('------初始化完成------')
console.log(this.message)
console.log(this.$el)
},
beforeMount () {
console.log('------挂载前---------')
console.log(this.message)
console.log(this.$el)
},
mounted () {
console.log('------挂载完成---------')
console.log(this.message)
console.log(this.$el)
},
beforeUpdate () {
console.log('------更新前---------')
console.log(this.message)
console.log(this.$el)
},
updated() {
console.log('------更新后---------')
console.log(this.message)
console.log(this.$el)
}
})
</script>
我们先看看首次加载时,输出了啥
从上面我们可以看出几点,
下面我们再看个例子
var vm = new Vue({
el: '#app',
data: {
message: 'hello world'
},
template: '<div>我是模板内的{
{message}}</div>',
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
beforeCreate() {
console.log('------初始化前------')
console.log(this.message)
console.log(this.$el)
},
created () {
console.log('------初始化完成------')
console.log(this.message)
console.log(this.$el)
},
beforeMount () {
console.log('------挂载前---------')
console.log(this.message)
console.log(this.$el)
},
mounted () {
console.log('------挂载完成---------')
console.log(this.message)
console.log(this.$el)
},
beforeUpdate () {
console.log('------更新前---------')
console.log(this.message)
console.log(this.$el)
},
updated() {
console.log('------更新后---------')
console.log(this.message)
console.log(this.$el)
}
})
我们在new Vue实例的时候直接传入了一个template,这时候我们再看输出
这么看是不是就很清晰了啊 ,在beforeMount的时候,$el还是#app, 但是在mounted的时候就变成模板的div了,是不是因为我们传了个template啊,所以,他直接将这个template转换成render函数啦。再渲染成真实dom后,用渲染出来的真实dom替换了原来的$el。
下面我们删除上面的template, 点击按钮更改下message,查看输出
哎。。。有没有看到一个很奇怪的东西啊,在beforeUpdate中输出的$el居然和updated里面输出的是一样的。这不对啊,以我们上面所说的逻辑的话,beforeUpdate内的$el应该是更新前的啊。这是怎么回事呢。这时候我们先来看一下mounted里面的。mounted里面我们看到p标签内依旧是hello world 对不对,其实这是因为,我是先点击了#app那个div的箭头,将这个div展开了以后,我再点击的按钮去更改了message,所以mounted里面还是原来的。那我现在如果先不展开mounted里面的div的话,我们来看看会怎么样
可以看到,初始输出,其实是这样的,我们看不到#app内的东西,需要点击箭头展开才能看到,现在,我不展开,然后我先点击按钮去改变message, 等beforUpdate和updated都执行完成后,我们再来一起展开,看下会怎么样
这是点击改变了message后的截图,然后我们现在展开div看看
看到没有,我们发现什么啦,怎么现在mounted里面的$el也变成更新后的啦。
呵呵,不要慌,其实啊,因为this.$el是一个对象,其实本质就是一个指针,当我们刚console.log输出的时候,其实并没有显示内容,而当我们点击箭头去展开这个div的时候,将指针指向了当前的$el,所以我们看到的才会都是改变后的$el。这也就是为什么之前mounted里面的$el是改变之前的值,而现在是改变之后的值了,因为之前那张图,我是先展开了mounted中的div,再去改变的message。下面我们再来验证下是不是这么回事
怎么验证,我们修改下代码
mounted () {
console.log('------挂载完成---------')
console.log(this.message)
console.log(this.$el.innerHTML)
console.log(this.$el)
},
beforeUpdate () {
console.log('------更新前---------')
console.log(this.message)
console.log(this.$el.innerHTML)
console.log(this.$el)
},
updated() {
console.log('------更新后---------')
console.log(this.message)
console.log(this.$el.innerHTML)
console.log(this.$el)
}
我们增加一个输出 this.$el.innerHTML, 再查看结果
这么看是不是就很明了啦,beforeUpdate里面的$el的内容,确实还是改变之前的,而我们之前看到的,只是因为我们后面展开时指针指向了当前值才导致的,是个视觉差而已。
后面两个销毁的,我就不举例说明了,没啥说的。下面我们再看一个问题,就是如果我们没有设置el时,会怎么样,我们在之前的生命周期图中,是说过,当没有找到el时, 说是不是会等待vm.$mount(el) 啊,这句话啥意思,我们来看一下
首先,我们看下,vue源码中,
在执行完,beforeCreate和created之后,是做了个判断,当存在el时,调用了 $mount方法,created之后的步骤,就是在这里面去走的。那如果没有el呢, 生命周期图中是说等待vm. $mount调用。那是不是只能等待我们手动去调用啊。
var vm = new Vue({
data: {
message: 'hello world'
},
// template: '<div>我是模板内的{
{message}} <button @click="changeMsg">点我</button></div>',
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
beforeCreate() {
console.log('------初始化前------')
console.log(this.message)
console.log(this.$el)
},
created () {
console.log('------初始化完成------')
console.log(this.message)
console.log(this.$el)
},
beforeMount () {
console.log('------挂载前---------')
console.log(this.message)
console.log(this.$el)
},
mounted () {
console.log('------挂载完成---------')
console.log(this.message)
console.log(this.$el.innerHTML)
console.log(this.$el)
},
beforeUpdate () {
console.log('------更新前---------')
console.log(this.message)
console.log(this.$el.innerHTML)
console.log(this.$el)
},
updated() {
console.log('------更新后---------')
console.log(this.message)
console.log(this.$el.innerHTML)
console.log(this.$el)
}
})
这个时候,我们删除了el属性,看看结果
是不是只走了前面两个生命周期啊,后面就没走了,这个时候其实就是在等$mount被调用了,那我们加个按钮,点击按钮,手动调用一下$mount看会怎样
没点击之前
点击后
可以看到,生命周期继续往下走了。
这时候不知道大家是不是想起来,看到有些vue项目的main.js里面是这样的
export default new Vue({
el: '#app',
router,
store,
i18n,
render: h => h(App)
})
而有些vue项目中人家用的又是这样的
export default new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount('#app')
其实后者,就相当于是手动调用了$mount了。
好了,言尽于此,有没有看懂的朋友,请直接私信或者评论。
文章浏览阅读581次,点赞2次,收藏5次。00为了形成一个体系,想将前面学过的一些东西都拉来放在一起总结总结,方便学习,方便记忆。攻防世界 Pwn 新手攻防世界 Pwn 进阶 第一页01 4-ReeHY-main-100超详细的wp1超详细的wp203 format2栈迁移的两种作用之一:栈溢出太小,进行栈迁移从而能够写入更多shellcode,进行更多操作。栈迁移一篇搞定有个陌生的函数。C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 _pwn snprintf
文章浏览阅读6.2k次,点赞2次,收藏5次。浅谈数据库—数据库系统的概述1.基础概念解释1.数据与信息(1)信息的定义。人脑对现实世界事物的存在方式、运动状态以及事物之间的抽象反映。信息是客观存在的,人类有意识的对信息进行采集加工、传递,从而形成了各种消息、情报、指令、数据以及信号。(2)数据的定义。数据是由用来记录信息的可识别的符号组合的,是信息的具体表现形式。2.数据处理与数据管理 数据处理是将数据转换成信息的过程,包括..._实现一个基于sql server数据库的应用(可以改用其他数据库),要求实现基本的crud(增
文章浏览阅读1.2w次。关于在PLSQL中实现DEBUG调试功能的方法2017年04月07日 14:27:52 samt007 阅读数:2179 标签: oracle调试plsql 更多个人分类: Oracle PL/SQL技巧前言 一个健康的PLSQL,应该都带有一套完整的调试逻辑。特别是那些功能很复杂的PLSQL,就更加有必要具备调试功能了。否则,当PLSQL处理数据出现问题的时候,分析(处理)起来会相..._plsql debug
文章浏览阅读885次。R文件报错,导致整个项目报红,清理工程,重新编译都不能解决,下面两种方法不能解决 Clean Project Rebuild Project 打开Android Studio菜单的Help然后点击Edit Custom Properties再写入# custom Android Studio propertiesidea.max.intellis..._r资源怎么找
文章浏览阅读1.6k次。已知一张图片宽为1024,高为768.img = img[80:550, 430:650];80~550代表取得的高度范围。430~650代表取得的宽度范围。_opencv提取快递地址
文章浏览阅读92次。Day1:OpenCV安装及处理图像00 安装在Prompt中输入pip install opencv-python,如果报错找不到匹配的版本可以在清华镜像中寻找合适版本,放到Scripts文件夹中,然后打开到该路径下用pip install xxx.whl安装,可以通过import cv2验证是否安装成功,若依然报错,可能是缺少MSVCP140.DLL模块,可以在官网下载。01 读写图片import cv2import numpy as np# 读入图像img = cv2.imread('i_学图像处理装opencv哪个版本
文章浏览阅读783次,点赞20次,收藏18次。国微前三年总包每年都比华子高将近20w,但是担心国微是反向,而且是做特种装备的,不好跳槽。1月底参加了京东方的全球博士专项活动,报销来回路费,然后去进行了一次比较简单的面试,准备了ppt,没机会讲,就问了一些专业方面的问题,没想到后续就不用再面试了,将对象转换为数组,数组中的每个元素都是一个对象,包含对象的属性以及对象的父节点和子节点。s = str(input())根据题意,把所有英文做了对应映射的字典,找到字典中的字符,转换成str加到字符串尾,如果不是,直接加就行了maping = {'
文章浏览阅读325次。“敢破敢立,即有无限可能。”本期供稿:文同学编辑:小誉大家好,我是誉天数通班的文同学。终于拿到了期盼已久的华为HCIE R&S证书,心里久久不能平静。回想起这半年的HCIE学习之路,有艰辛,也有收获成功后的喜悦。整个备考过程几乎不亚于当年的升学考试。对于非网络专业的我来说,面对华为最高等级的认证,难度大、挑战大,压力也非常大。也正因为如此,我一度非常庆幸自己的选择——到誉天来学习。成为誉天大家族的一份子,是我考证道路上迈出的最正确一步。这里要感谢誉天,也要特别感谢胡老师和大祥老_hcie开班
文章浏览阅读404次。4G改变生活,5G改变社会,只是这个改变并没那么容易。2020年是ITU所定义的全球5G商用元年,而中国则还要早一年。据中国信息通信研究院,2021年1~4月国内5G手机出货量为9126.7万部,占市场总体的72.7%,同比增长38.4%。这在一定程度上反映了5G通信在个人用户层面的推进速度。但5G不止于手机,在万物互联时代,必须提前搭建好一条条高速路,5G因此无可争议地成为新基建之首。相比4G,5G在初始阶段就明确规划了三大应用场景:增强移动宽带,其峰值速率将是4G网络的10倍以上;海量机器通信,_5g 终端响应
文章浏览阅读3.3k次,点赞5次,收藏11次。首先展示一下项目目录树:.├── frf_demo # 存放整个项目│ ├── apps # 存放应用模块包│ │ ├── cart # 购物车模块│ │ │ ├── __init__.py # 创建cart应用蓝图│ │ │ ├── models.py # 数据库模型│ │ │ ├── urls.py # 创建api,进行..._flask-rest + blueprint
文章浏览阅读1.2k次。应用层域名系统DNS域名系统DNS(Domain Name System)是互联网使用的命名系统,用来把便于人们使用的机器名字转换为IP地址。互联网的域名系统DNS被设计成为一个联机分布式数据库,并采用客户服务器方式。互联网的域名结构互联网采用层次树状结构的命名方法,采用这种命名方法,任何一个连接在互联网上的主机或路由器,都有一个唯一的层次结构的名字,即域名(Domain Name)。“..._telnet ctf
文章浏览阅读515次,点赞2次,收藏6次。描述在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。比如 1 3 2 的逆序数就是1。格式输入格式第一行输入一个整数T表示测试数据的组数(1<=T<=5)每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=100000)随后的一行共有N个整数Ai(0<=Ai<1000000000),表示数列中的所有元素_即逆置数的个数;