前言

上篇文章咱们已经简单介绍了 Vue 的基本模板语法,接下来本文主要还是用来介绍 Vue 的实例属性的用法,及其注意点等!我会尽可能的结合我自己实际项目开发中的经验,将可能被忽略的点,以及遇到的坑给罗列出来,当然由于水平有限,可能会有遗漏或错误,还望各位不吝指出!

实例属性

Vue 实例对象,包含有 挂载的dom元素el数据data接受外部数据的props对象混入对象mixins方法methods计算属性computed侦听器watch组件注册对象components,生命周期钩子: 创建前beforeCreate创建后created挂载前beforeMount挂载后mounted数据更新前beforeUpdate数据更新后updated组件卸载前beforeDestroy组件卸载后destroyed,过渡效果钩子:keep-alive 组件激活activatedkeep-alive 组件停用deactivated等等;

属性详解

挂载的dom元素el:

  • 用于挂载实例的 DOM 元素

数据data:

  • 用于存放/注册实例数据
  • 防止对象引用产生错误,推荐使用函数返回一个新的对象

接受外部数据的props对象:

  • 用于注册需要从实例外部获取的数据/属性
  • 可以使用数组方式,仅能用于注册,将每个属性名作为数组的元素:props: ['value', 'name']
  • 可以使用对象方式,可以设定类型,是否必须,默认值等属性:
1
2
3
4
5
6
7
8
9
10
props: {
value: {
// 是否必须
required: true,
// 类型
type: String,
// 默认值
default: '',
}
}

当prop属性的类型为数值类型:string, number, boolean, undefined, null时可以直接设定属性值 default: '',否则为防止引用导致错误需要使用方法返回:

1
2
3
4
5
6
7
8
9
10
11
12
props: {
value: {
// 是否必须
required: true,
// 类型
type: Object,
// 默认值
default: function() {
return {};
}
}
}

prop属性的类型设定时必须为原生构造函数中的一个:String, Number, Boolean, Array, Object, Date, Function, Symbol,且可以为多种类型:type: [Object, Array]

混入对象mixins:

混入我们可以理解成把一堆可复用方法提到一个没有模板的vue实例中,mixins 拥有 Vue 实例的完整属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var mixin = {
data: function() {
return {
common: []
};
},
props: [],
methods: {

},
mounted: function() {

},
};

我们可以将 mixins 当成是一个除了模板以外的 Vue 实例对象,值得注意的是,在将 mixins 属性混入到组件中时,数据对象在内部会进行浅合并 (一层属性深度),在和组件的数据发生冲突时以组件数据优先。,也就是说在组件中包含和 mixins 对象同名的属性时,最终会以组件内的属性覆盖 mixins 中的属性!

而且:值为对象的选项,例如 methods, components 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。

另外:同名钩子函数将混合为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。,也就是说类似于生命周期钩子: 创建前beforeCreate创建后created … 等等函数钩子都会被执行,而不会进行覆盖,但是 mixins 中的钩子函数会比组件中的钩子先执行!

计算属性computed:

计算属性可以理解为 data 属性的自定义补充属性,方便将模板中的复杂的表达式使用计算属性进行替代,但是,当且只当某个属性依赖某些属性,且之间只有固定的关系时使用,即该属性只依赖某个属性根据某些关系推导得来,其他任何属性或者操作,都无法改变该属性的值,而且计算属性可以写成 gettersetter 的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var vue = new Vue({
data: function() {
return {
list: [],
page: 2,
};
},

computed: {
// 根据list数据是否返回来设置loading
loading: function() {
return !(this.list && this.list.length > 0);
},

pageNum: {
get: function() {
if (this.list && this.list.length > 0 && this.page) {
return this.list.length / this.page;
}

return 0;
},

set: function(num) {
if (this.list && this.list.length > 0) {
this.page = this.list.length / num;
return;
}

this.page = 0;
}
}
},
})

就像上面提到的那样,一旦将属性设定为计算属性,那么该属性的值,只能由计算属性所依赖的属性根据某些关系计算出来,而不来在代码中单独修改该属性的值,就像上面的例子中的 loadingpageNum ,只能根据 list 属性根据关系计算得来,而在 list 属性无变化的情况下,直接修改loadingpageNum是不起作用的:

1
2
3
// 由于list为空数组
// 所以单独设置loading的值无效
this.loading = false;

侦听器watch:

侦听器是用来检测 Vue 实例属性值变化而自定义某些操作,watch 侦听器属性,既可以使用 回调函数 方式来使用,也可以设置对象来定义,通常在需要检测的属性值为 值类型 时,直接使用 回调函数 方式,而当需要检测的属性值为 引用类型时 使用 对象方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var vue = new Vue({
data: function() {
return {
list: [],
page: 2,
};
},

watch: {
page: function(newVal) {
if (newVal > 0) {
this.getListData();
}
},

list: {
deep: true,
immediate: true,
handler: function(val) {
if (val && val.length > 0) {
// do something
}
}
}
},
})

回调函数 方式:该回调函数有两个参数: newValueoldValue,分别用来表示变化后的值和变化之前的值;

对象方式 方式:该对象包含 deepimmediatehandler,三个属性,其中 deep 属性的值表示是否对待检测属性进行深层次的监控,及该属性的内部属性值的变化,如 对象子属性的子属性值的变化;immediate 属性的值表示是否以待检测属性的初始值触发回调函数;handler 为回调函数,同样有 newValueoldValue 两个参数!

计算属性和侦听器的区别

计算属性 更多的是用来依赖某些值计算出结果,并且只有在获取该属性值的时候;该属性才会根据最新的依赖值进行计算,而依赖属性的变化并不会主动触发计算属性的计算!比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var vue = new Vue({
data: function() {
return {
list: [],
page: 2,
};
},

computed: {
// 当pageNum并不会被关联到html模板上时
// 仅仅只是在js代码中进行计算或者保存的话
// 该计算属性不会根据最新的依赖值进行计算
pageNum: function() {
console.log(11111);
if (this.list && this.list.length > 0) {
return this.list.length / 4;
}
},
},

mouted() {
// 当前list的值已经被改变,但是并不会触发计算属性进行计算
// 即计算属性中的console.log不会被触发
this.list = [
{},
{},
];

// 只用当获取pageNum的值时,才会被触发
const a = this.pageNum;
}
})

这是因为从根本上说,计算属性只是设置了该属性对象的 getter 属性,也只有在 get 操作时才会触发!所以,很多时候并不能把计算属性当成侦听器来用,否则可能会无法产生预期的效果!

侦听器 更多的是用来根据某个属性值的变化,进行某项操作,而不仅限于去计算某些属性的值!比如,当属性 a 的值发生改变时,触发某个函数或者发送一下请求等类型的操作!

到这里实例属性基本都介绍的差不多了,剩下的如 components 是用来注册子组件,methods 是用来注册方法的,beforeCreatemounted 等都是生命周期钩子;这些的用法和作用都比较简单,就不一一进行详细介绍了!并且关于上面所介绍的内容,具体可以看看下面的代码示例,对于某些注意的地方,在代码的注释中都进行了说明!

Vue 实例代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/** 
* Vue实例属性示例及说明
*/

import Vue from 'vue';
import common from './mixins/common';
import InputItme from './components/InputItme';

const vm = new Vue({
// 实例挂载元素
el: document.getElementById('app'),

// 数据对象
// 防止对象引用产生错误,推荐使用函数返回一个新的对象
data: function() {
return {
text: 'hello',
value: '',
};
},

// 接受外部数据
// 可以是对象,也可以是数组
props: {
// 假设需要外部传入表格数据
tableDate: {
// 设定数据类型 - 用于检验数据
type: Object,
// 设置默认值
// 如数据类型为数值类型:string, number, boolean, undefined, null
// 可以直接等于值:`default:2`
default: function() {
return [];
},
},
},

// 混入对象 - 用于注册可复用功能
// minxins对象内可以包含所有Vue实例属性
// 如:data, props, watch, minxins, mothods等
minxins: [ common ],

// 侦听器
// 用于侦察数据变化,以做出相应处理
watch: {
// 这里可以使用对象模式 or 方法模式

// 对象模式 - 主要用于监听引用类型的数据
tableDate: {
// 是否对数据进行
// 用于侦听对象 or 数组等内部属性值的变化
deep: true,

// 用于设置是否以属性的当前值触发回调
// 可以理解为以默认值触发
immediate: true,

// 回调函数
// newVal 变化后的值
// oldVal 变化前的值
handler: function(newVal, oldVal) {
// do something
}
},

// 方法模式 - 主要用于监听值类型的数据
// newVal 变化后的值
// oldVal 变化前的值
value: function(newVal, oldVal) {
// do something
},
},

// 子组件注册
components: {
// 如注册一个 input 组件
InputItme,
}

// 方法注册对象
methods: {
doSomeThing: function() {
// do something
},
},

// 实例创建前触发的构造
// 注意当前实例未创建,方法内无法使用实例 this
// 可在当前方法中请求 - 无法赋值给实例属性
beforeCreate: function() {
// do something
},

// 实例创建后触发
// 方法内可以使用实例 this
// 一般用来发送 ajax 请求数据 - 并赋值给 this.data 对象的属性
created: function() {
// do something
},

// 实例挂载前触发
beforeMount: function() {
// do something
},

// 实例挂载后触发
// 在mounted之前由于未真正挂载到 DOM 元素上,无法进行 DOM 相关操作
mounted: function() {
// do something
},

// 数据更新时调用 - 在虚拟 DOM 改变前调用
beforeUpdate: function() {
// do something
},

// 数据更新后调用 - 在虚拟 DOM 改变后调用
// 但该钩子不保证所有的子组件也都一起被重绘
updated: function() {
// do something
},

// 实例销毁前粗发
// 可用用于销毁数据,释放内存
beforeDestroy: function() {
// do something
},

// 实例销毁后调用
// 调用后,实例被销毁,可以访问this
destroyed: function() {
// do something
},
});

至此,我们已经介绍了大部分实例属性,入门部分文章也算是结束了,接下来我们将一一介绍 组件开发自定义指令自定义插件自定义过滤器minxins混入等内容!

转载说明

本文允许全文转载,转载请注明来源:
平凡公子 - vue从入门到精通入门篇之实例属性