问题1:v-for和v-if不要绑定在同一个元素上

场景

<template>
	<ul>
		<li
			v-for="value in lists"
			v-if="value.flag"
			:key="value.id">
			
		</li>
	</ul>
</template>

原因

v-for和v-if绑定在同一个元素上会带来一些性能上的影响。v-for和v-if一同使用时,v-for的优先级要高于v-if。所以上述场景的渲染会经过如下的运算:

this.lists.map(function(value){
  if(value.flag){
    return value.content
  }
})

因此,哪怕我们只渲染一小部分的数据,也得在每次重新渲染的时候遍历整个列表。

解决

官方给出的建议是在计算属性上过滤之后再进行遍历。

computed: {
  showLists() {
    return this.lists.filter(function(value){
      return value.flag
    })
  }
}
<template>
	<ul>
		<li
			v-for="value in showLists"
			:key="value.id">
			
		</li>
	</ul>
</template>

问题2:路由跳转,不会触发created和mounted等钩子

原因

由于Vue会复用相同的组件,例如/page?id=1跳转到/page?id=2,组件将不会执行created、mounted等钩子函数。

解决

1、使用watch监听路由的变化

watch: {
  $route(to, from){
    // todo...
  }
}

2、给router-view绑定一个unique key

<router-view :key="$route.fullPath"></router-view>

ps:不建议使用,因为每次渲染要消耗一些性能。

问题3:如何捕获Vue错误

全局捕获:Vue.config.errorHandler

Vue.config.errorHandler = function(err, vm, info) {
  // ...
}

指定组件的渲染和观察期间未捕获错误的处理函数。处理函数被调用时,可获取错误信息和Vue实例。

组件捕获:errorCaptured

当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

errorCaptured 是一个钩子函数,在没有阻止传播的情况下,该错误依然会被全局的 errorHandLer 捕获,所以这个更适合于处理即时性的错误,性质上有点类似于 try catch。