0%

Vue2躲坑手记

组件的data

组件的data是一个function,和实例中不一样,这个比较简单。

组件参数名称

在js代码中,我们有命名变量的固定习惯,一般都用驼峰命名规则。这个习惯最好不要带到Vue组件参数命名中来,我习惯一律采用小写,避免犯错的可能性。具体的原因这里已经说的很清楚了。

组件参数类型

众所周知,js是类型不敏感的,在定义Vue组件参数一般都采用简写,不声明参数类型。所以传参的时候类型判断就很有必要了。这里有一个例子,string和number类型的参数用作比较时尤其要小心。最好是在参数声明时就声明参数类型。

数据改变了界面怎么就不改变?

数组

更改数组内容,不要使用下标操作。
我曾经碰到了这样的问题,在我修改完数据后,界面纹丝未动,根本就没有触发更新渲染。
我做的操作是交换数组中的两项的位置,有问题的代码是这样的:

1
2
3
4
let dragItem = {...curTripPlan[dragIndex]};
let containerItem = {...curTripPlan[containerIndex]};
curTripPlan[dragIndex] = { ...curTripPlan[containerIndex]};
curTripPlan[containerIndex] = { ...dragItem}

这里,我首先得到了两个下标对应的数组项,然后通过下标交换了两项的内容,通过调试工具,能够看到数组内容发生了变化,但是界面没变化。后来我把代码修改成了这样:

1
2
3
4
let dragItem = {...curTripPlan[dragIndex]};
let containerItem = {...curTripPlan[containerIndex]};
curTripPlan.splice(dragIndex, 1, containerItem);
curTripPlan.splice(containerIndex, 1, dragItem);

做了两次操作:删除原来位置的内容,添加上新的,这次好了。
其实官方文档中已经说的很清楚了,Vue渲染机制只会响应数组的以下操作:push()、pop()、shift()、unshift()、splice()、sort()、reverse(),只不过我们用下标太习惯了。

同样的道理,也不要直接设置数组的长度

对象

上面提到的官方文档中也讲了对象属性改变触发渲染的条件。这也是为什么Vue和Vuex都建议对象做数据的情况下要声明所有的属性。

针对以上两种数据类型,我推荐采用es6新增的“…”展开,构建新的数组或者对象,进行值的覆盖。

失效的watch

监听的内容不对

通常的情况是这样的:渲染依赖对象的一个属性,但却监听的是这个对象,比如:

1
2
3
4
5
watch:{
item:function(newVal,oldVal){
...
}
}

正确的写法如下:

1
2
3
4
5
6
7
watch:{
'item.traffic':{
handler(newVal,oldVal){
...
},
}
},

这样当对象属性发生变化后就会被监听到。

watch的第一次

watch的一个特点是对于监听内容的第一次赋值不会有响应。但如果你恰好依赖第一次赋值,那么该怎么办?可以加immediate参数,下面是个例子:

1
2
3
4
5
6
7
8
watch:{
'item.trafficWay':{
handler(newVal,oldVal){
...
},
immediate: true
}
},

watch还有个deep参数,可以控制监听对象的深度。

PS:虽然有这两个参数,但是都不推荐使用,immediate已经违背了watch的初衷,而deep无疑会增加运行的开销。更近一步而言,watch都应少用。