一.vue框架的生命周期函数
Vue.js(读音 /vjuː/, 类似于 view)是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
1.什么是vue生命周期?有什么作用?
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做 生命周期钩子 的函数,这给了用户在不同阶段添加自己的代码的机会。(ps:生命周期钩子就是生命周期函数)例如,如果要通过某些插件操作DOM节点,如想在页面渲染完后弹出广告窗, 那我们最早可在mounted 中进行。
所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此 this 与你期待的 Vue 实例不同,this.fetchTodos 的行为未定义
2.vue框架生命周期函数的阶段
Vue.js借鉴了Angular以及React的一些核心思想,综合各自的长处进行了操作以及性能等方面的优化,进而打造出一款性能更优,学习更容易的MVVM框架。
2.1 vue与Angular.js相比较:
1、vue在设计之初参考了很多angularjs的思想
2、vue相对比与angular比较简单
3、 vue相对比与angular比较小巧,运行速度快
4、 vue与angular数据绑定都可以用{{}}
5、vue指令用v-xxx angularjs用ng-xxx
6、vue数据放在data对象里面,angular数据绑定到$scope对象上
2.2.生命周期函数的阶段(4个阶段,每个阶段两个钩子函数)(目前常用的是8个)
创建(初始化阶段)
创建钩子是在您的组件中运行的第一个钩子。 它们允许您在组件甚至在添加到DOM之前执行操作。 与任何其他钩子不同,创建钩子也在服务器端渲染期间运行。
如果您需要在客户端呈现和服务器渲染期间在组件中设置东西,请使用创建挂钩。同样在创建钩子忠 您将无法访问模板。
1.beforeCreate
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之 前被调用;
beforeCreate 钩子在组件的初始化前运行。 data 还没被附加上 reactvie 特型,events 也还没建立好。
2.created
在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
在 created 钩子中,你能够访问 reactive data 和 events。但是模板和虚拟DOM无法访问
export default {
data: () => ({
property: 'lys'
}),
computed: {
propertyComputed() {
console.log('I change when this.property changes.');
return this.property;
}
},
created() {
this.property = 'laoergege';
console.log(`propertyComputed is ${this.propertyComputed}`)
}
}
Mounting hook 允许我们在组件渲染前后访问组件。当然他们不会再服务端渲染被调用。如果您需要在初始化时为组件提取一些数据。 为此而使用created (or created + activated for keep-alive components),特别是如果在服务器端呈现期间需要该数据。
3.beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。
beforeMount钩子在初始渲染发生之前和模板或渲染函数被编译之后运行。
beforeMount() {
console.log(`this.$el doesn't exist yet, but it will soon!`);
console.log(`this.$el is ${this.$el}`);
}
4.mounted
el 被新创建的 vm. e l 替 换 , 并 挂 载 到 实 例 上 去 之 后 调 用 该 钩 子 。 如 果 r o o t 实 例 挂 载 了 一 个 文 档 内 元 素 , 当 m o u n t e d 被 调 用 时 v m . el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm. el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.el 也在文档内。
注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
使用 mounted 钩子,你将拥有访问组件模板能力。mounted 钩子是经常使用的生命周期钩子。我使用最多的方式是在 created 里获取组件需要的数据或者在 mounted 中修改 DOM。
I'm text inside the component.
该钩子在服务器端渲染期间不被调用。
更新(数据监测并更新渲染)
每当您的组件使用的响应属性更改或其他原因导致重新呈现时,将调用更新的钩子。 它们允许您钩入组件的watch-compute-render循环。
使用情况:如果您需要知道您的组件什么时候重新渲染,或许用于调试或分析。
避免情况:如果您需要知道组件上的 reactive 属性何时更改。 为此而使用computed 属性 或 watcher。
5.beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
beforeUpdate 钩子在您的组件的数据更改之后运行,更新周期开始,就在DOM修改和重新渲染之前。 它允许您在实际渲染之前获取组件上任何反应数据的新状态。
6.updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated:
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}
该钩子在服务器端渲染期间不被调用。
更新的钩子在您的组件和DOM重新呈现数据更改后运行。 如果您需要在属性更改后访问DOM,这可能是最安全的做法。
{{counter}}
7.activated
keep-alive 组件激活时调用。
keep-alive是vue特定用来做缓存的标签
该钩子在服务器端渲染期间不被调用。
可以使用它们来获取组件的数据或处理状态更改,相当于 created 和 beforeDestroy,而无需执行完整的组件重建
8.deactivated
keep-alive 组件停用时调用。
keep-alive是vue特定用来做缓存的标签
该钩子在服务器端渲染期间不被调用。
可以使用它们来获取组件的数据或处理状态更改,相当于 created 和 beforeDestroy,而无需执行完整的组件重建。
销毁
销毁挂钩允许您在组件销毁时执行操作,例如清理或分析发送。 当您的组件被拆除并从DOM中删除时,它们将触发。
9.beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。beforeDestroy 在拆卸组件之前被回掉。 您的组件仍将完全存在。 如果您需要清理事件或取消订阅,则可能是DDestroy可能要执行此操作。
该钩子在服务器端渲染期间不被调用。
10.destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
当 destory 钩子被调用时,意味你的组件完全被销毁。你可以利用最后这钩子做些最后清理或者通知服务器该组件被销毁了。
该钩子在服务器端渲染期间不被调用。
11.errorCaptured
vue.js版本2.5.0+ 新增
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
你可以在此钩子中修改组件的状态。因此在模板或渲染函数中设置其它内容的短路条件非常重要,它可以防止当一个错误被捕获时该组件进入一个无限的渲染循环。
错误传播规则
1.默认情况下,如果全局的 config.errorHandler
被定义,所有的错误仍会发送它,因此这些错误仍然会向单一的分析服务的地方进行汇报。
2.如果一个组件的继承或父级从属链路中存在多个 errorCaptured
钩子,则它们将会被相同的错误逐个唤起。
3.如果此 errorCaptured
钩子自身抛出了一个错误,则这个新错误和原本被捕获的错误都会发送给全局的 config.errorHandler。
4.一个 errorCaptured
钩子能够返回 false 以阻止错误继续向上传播。本质上是说“这个错误已经被搞定了且应该被忽略”。它会阻止其它任何会被这个错误唤起的 errorCaptured
钩子和全局的config.errorHandler
总结
Vue 组件的生命周期分为四个阶段,每个阶段有两个生命钩子,注意前后钩子。
创建阶段:主要用于组件创建时,获取数据设置组件。
1.beforeCreate
2.created(能够访问创建成功的组件实例,但不能访问 模板,el 或 DOM)
挂载阶段:主要用于访问组件 DOM。
3.beforeMount
4.mounted(能够访问组件模板)
更新阶段:数据变化,组件重新渲染。
5.beforeUpdate(能够访问组件更新后的数据,但无法访问 DOM)
6.updated(能够访问 DOM)
.销毁阶段:(用于销毁组件,做清理工作)
7.beforeDestory(销毁前还能访问组件实例)
8.destory
获取组件的数据或处理状态更改,相当于 created 和 beforeDestroy
9.activated
10.deactivated
捕获错误钩子函数
11.errorCaptured
2.3.第一次加载页面会触发哪些钩子?
beforeCreate, created, beforeMount, mounted
二.Vue框架组件间的传值
2.1.什么是组件?
组件系统是vue的另一个重要概念,它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用,因此,几乎任意类型的应用界面都可以看成一个组件树:
组件的作用既可以从父作用域将数据传到子组件,也可以将把组件内部的数据发送到组件外部,可以实现互相传送数据
2.1.1组件的使用
注:组件之间跨域相互嵌套
(一)组件使用之全局注册
我们在一级目录下新建一个全局注册.html文件,在该文件中介绍全局注册,我们还需引入vue.js文件
(二)局部注册
实际项目中,我们不必把每个组件都注册到全局,我们可以通过某个Vue实例/组件的实例选项components注册仅在其作用域中可用的文件
在一级目录下新建一个局部注册.html
下图步骤就是注册一个简单的局部组件
....
自定义组件会被当做无效的内容,因此会导致错误的渲染结果,解决方法是使用特殊的 is 特性:
....
2、组件里面data一定要用function方式,不然会传址
如果我们有多个组件,而这些个组件各自有data对象,其实是共享一个data对象,因此会相互影响,所以要写成
data: function () {
return {
}
}
这样每个组件都会有它自己的data对象,互相之间不会影响
而且data里面的数据,只能在组件的template里面才能生效
(一)直接引入
模板中使用标签
引入
(二)通过is属性动态引入
keep-alive是vue特定用来做缓存的标签
2.2 组件间的传值
VUE中组件之间传值,总结来讲有三种情况,分别是:父组件对子组件、子组件对父组件以及兄弟组件之间传值以及调用。
一、父组件==>子组件
方式1:常用的
原理:父组件-子组件:在子组件标签上绑定自定义属性,属性值为父组件需要传递的数据,子组件内部通过props
接受该组件属性名(数组形势)
可以看下下面的代码:
组件传旨-父组件-子组件
父组件
{{info}}
子组件
接受父组件的数据--{{name}}
这里面是一个嵌套的组件,父组件(v-parent)与子组件(v-child),父组件通过绑定事件(@click=“send()”),send()事件 通过自身methods将要把传给子组件的数据发送出去,子组件通过设置**props
**接受数据,数据接受由子组件设置一个变量,加双引号,用数据形式接受
方式2:通过this.$attrs
获得
原理:父组件-子组件:通过this.$attrs
可以获取到父组件传递过来的数据
具体代码如下:
组件注册基本和上面一致,但这个是通过this.$attr获取
2.子组件=>父组件
原理:子组件-父组件:在子组件标签上绑定自定义事件,值为父组件函数
子组件内部通过$emit给该事件推送数据,父组件内部通过函数参数进行接受
具体代码如下:
子组件-父组件
父组件
接受子组件的数据--{{infos}}
子组件
{{info}}
可以再看下同等的例子:
1.父组件parent代码如下
{{ msg }}
父组件接手到的内容:{{ username }}
2.子组件son代码如下:
{{ sonMsg }}
子组件接收到内容:{{ psMsg }}
1.通过npm加载vuex,创建store.js文件,然后在main.js中引入,store.js文件代码如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state = {
author:'Wise Wang'
};
const mutations = {
newAuthor(state,msg){
state.author = msg
}
}
export default new Vuex.Store({
state,
mutations
})
2.父组件parent代码如下:
{{ msg }}
父组件接手到的内容:{{ username }}
3.子组件son代码如下:
{{ sonMsg }}
子组件接收到内容:{{ psMsg }}
这本书的作者是:{{ $store.state.author }}
3.兄弟组件之间
方式1
原理:兄弟组件之间:创建一个空的组件实例,将数据通过空的实例$emit发送数据,通过 $on 接受数据
具体代码如下:
平行组件
AAAAAA组件
{{info}}
BBBBBB组件
{{info}}
CCCCCC组件
接受AAA数据--{{infoa}}
接受BBB数据--{{infob}}
方式二
总线机制 解决非父子组件之间传值的问题
通过一个案例来实现该模式,当点击 even 时,yao 变为 even。当点击 yao 时,even 变为 yao。
首先 new 一个 Vue 的实例,将其赋值给 Vue.prototype.bus
。即给 Vue.prototype
上挂载了一个名为 bus 的属性。这个属性,指向 Vue 的实例。只要在之后,调用 new Vue()
或者创建组件的时候,每一个组件上都会拥有 bus 这个属性。都指向同一个 Vue 的实例。
通过 this.bus.$emit
向外触发事件,再借助生命周期钩子 mounted
通过 this.bus.$on
监听事件。
非父子组件间传值 Bus/总线/发布订阅模式/观察者模式)