来自Vue官网:https://cn.vuejs.org/v2/guide/instance.html#生命周期图示
什么是生命周期:
从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!
生命周期钩子:
就是生命周期事件的别名而已。即,生命周期钩子 = 生命周期函数 = 生命周期事件
beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始编译模板,此时在vue实例中不能操作dom。
beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示,此时在vue实例中可以操作dom
注意当页面数据改变进行刷新会执行此函数,在页面刷新频率高时不要让此函数有太多负担,否则影响运行效率
组件使用keep-alive
组件包裹,具有以下两个生命周期
生命周期执行顺序demo
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue生命周期测试title>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<input type="button" value="修改msg" @click="msg='No'">
<h3 id="h3">{{ msg }}h3>
div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
msg: 'ok'
},
methods: {
show() {
console.log('可以行show方法了,data、methods初始化完毕')
}
},
beforeCreate() { // 这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它
console.log('beforeCreate');
// this.show();//error,因为在 beforeCreate 生命周期函数执行的时候,data 和 methods 中的 数据都还没有没初始化
},
created() { // 这是遇到的第二个生命周期函数
console.log('created');
this.show();//没问题
// 在 created 中,data 和 methods 都已经被初始化好了!
// 如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作
},
beforeMount() { // 这是遇到的第3个生命周期函数,表示模板已经在【内存】中编辑完成了,但是尚未把 模板渲染到 页面中
console.log('beforeMount');
// 在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串
},
mounted() { //这是遇到的第4个生命周期函数,表示,内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
console.log('mounted');
// 注意: mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例,就静静的 躺在我们的内存中,一动不动
},
// 接下来的是运行中的两个事件
beforeUpdate() { // 这时候,表示我们的界面还没有被更新【数据被更新了吗? 数据肯定被更新了】
/* console.log('界面上元素的内容:' + document.getElementById('h3').innerText)
console.log('data 中的 msg 数据是:' + this.msg) */
console.log('beforeUpdate');
// 得出结论: 当执行 beforeUpdate 的时候,页面中的显示的数据未更新,此时data数据在内存中已更新
},
updated() {
console.log('updated');
// console.log('界面上元素的内容:' + document.getElementById('h3').innerText);
// console.log('data 中的 msg 数据是:' + this.msg);
// updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
}
});
script>
body>
html>
以上代码输出结果:
beforeCreate
created
可以行show方法了,data、methods初始化完毕
beforeMount
mounted
用来保存vue实例对象的数据。
data中的数据都是响应式的,但后添加的数据为非响应式的(没经过vue初始化),可以通过Vue的set方法往data中添加响应式的数据。
可以通过 vm.$ data 访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问 vm.a 等价于访问 vm.$data.a。
Vue component创建后data中的数据存方于此。
注意:
以 _ 或 $ 开头的属性 不会 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、API 方法冲突。你可以使用例如 vm.$data._property 的方式访问这些属性。
当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。否则,多个组件共享一个对象,一处数据改变,处处改变。
如果需要,可以通过将 vm.$data 传入 JSON.parse(JSON.stringify(…)) 得到深拷贝的原始数据对象。
demo
export default {
name: "ComponentName",
data( ){
return {
msg:'',
...
}
},
components: {
Comp,
...
},
methods: {
methodA(){
//todo
},
...
}
}
props有两种类型: 数组 、Object(用的多)
props: ['title', 'msg']
对象选项 | 值类型 | 说明 |
---|---|---|
type | 数据类型 | 如果传入数据为数组或Object则default要返回一个对象或数组 |
default | 指定默认值,any | 指定数据的默认值 |
required | Boolean | 定义数据是否必传,如果值为truthy且父组件为传该值则控制台打印警告 |
validator | func | 定义值的验证规则,该func返回一个Boolean进行校验 |
demo
// 对象语法,提供验证功能
props: {
age:{
type: Number,
default: 0,
required: true,
validator: function (value) {
return value >= 0
}
}
}
保存vue实例的方法。
注意:不能在methods中的方法使用箭头函数,因为箭头函数的上下文指向父级作用父,在函数中this不执行vue实例,当使用this引用data中的数据将出错(undefined)。
methods:{
//es6
methodA(){
},
//normail
methodB:function(){
},
//err this为undefined
methodC:()=>{
console.log(this)//undefined
}
}
用来保存子组件/模板。
指定已创建的实例之父实例,在两者之间建立父子关系。子实例可以用 this.$parent 访问父实例,子实例被推入父实例的 $children 数组中。
注意:节制地使用 $parent 和 $children - 它们的主要目的是作为访问组件的应急方法。更推荐用 props 和 events 实现父子组件通信.
监听data或prop中的某个值的改变,值改变触发函数fn(newVal,oldVal)
,只有在vue响应式系统中的数据改变才会触发fn。
注意: 函数fn不应使用箭头函数。
计算属性可以同data中数据一样使用,一般是对props、data中的数据进行操作而形成的函数。当初始化vue实例,计算属性将被混入,最终computed属性和data中的属性几乎没有差别。
使用方式
computed:{
//只用读取功能
computedA(){
return this.msg.toUpperCase();
},
computedB:function(){
return this.msg.toUpperCase();
},
//具有读取和设置功能
computedC:{
get:function(){
},
set:function(){
}
}
}
过滤器,存储对数据处理的一些方法,常用的是日期转换处理。
概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;
<td>{{item.ctime | dataFormat('yyyy-mm-dd')}}td>
filters
定义方式:
filters: { // 私有局部过滤器,只能在 当前 VM 对象所控制的 View 区域进行使用
dataFormat(input, pattern = "") { // 在参数列表中 通过 pattern="" 来指定形参默认值,防止报错
var dt = new Date(input);
// 获取年月日
var y = dt.getFullYear();
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
// 否则,就返回 年-月-日 时:分:秒
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {
// 获取时分秒
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
}
}
使用ES6中的字符串新方法 String.prototype.padStart(maxLength, fillString=’’) 或 String.prototype.padEnd(maxLength, fillString=’’)来填充字符串;
注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
在创建vue实例会将mixins对象与vue实例对象进行合并。合并的数据和函数可以像vue实例本身的数据一样使用。
从实例结果中可以观察到,mixins中的声明周期钩子在vue实例的声明周期钩子之前被调用。
var mixin = {
created: function () {
console.log(1)
}
}
var vm = new Vue({
created: function () {
console.log(2)
},
mixins: [mixin]
})
// => 1
// => 2