面试题答案
一键面试常见问题
- 渲染性能问题:
v-for
优先级高于v-if
,所以每次v-for
循环时都会执行v-if
,这在列表数据量大时会严重影响性能。例如,有一个包含大量用户信息的列表,每个用户有一个isActive
字段,希望仅展示活跃用户:
<ul>
<li v-for="user in users" v-if="user.isActive" :key="user.id">
{{ user.name }}
</li>
</ul>
这里即使不活跃用户也会被循环创建,然后通过v-if
判断再销毁,浪费性能。
- 逻辑问题:当
v-if
依赖于v-for
作用域之外的数据时,可能导致难以理解的逻辑错误。例如:
<template>
<div>
<input type="checkbox" v-model="showOnlyActive">
<ul>
<li v-for="user in users" v-if="showOnlyActive && user.isActive" :key="user.id">
{{ user.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
showOnlyActive: false,
users: [
{ id: 1, name: 'user1', isActive: true },
{ id: 2, name: 'user2', isActive: false }
]
};
}
};
</script>
在这个例子中,v-if
的条件既依赖于外部数据showOnlyActive
,又依赖于v-for
中的user.isActive
,逻辑相对复杂,不易维护。
避免方法
- 计算属性法:通过计算属性过滤数据,然后在
v-for
中使用过滤后的数据。例如:
<ul>
<li v-for="user in activeUsers" :key="user.id">
{{ user.name }}
</li>
</ul>
export default {
data() {
return {
users: [
{ id: 1, name: 'user1', isActive: true },
{ id: 2, name: 'user2', isActive: false }
]
};
},
computed: {
activeUsers() {
return this.users.filter(user => user.isActive);
}
}
};
这样可以避免在每次v-for
循环时执行v-if
,提升性能,同时逻辑也更清晰。
- 在外层包裹元素使用
v-if
:如果v-if
的判断与v-for
中的数据无关,可以将v-if
放在包裹v-for
的外层元素上。例如:
<template>
<div>
<input type="checkbox" v-model="showOnlyActive">
<ul v-if="showOnlyActive">
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
showOnlyActive: false,
users: [
{ id: 1, name: 'user1', isActive: true },
{ id: 2, name: 'user2', isActive: false }
]
};
}
};
</script>
这样只有在showOnlyActive
为true
时,整个ul
及其内部的v-for
才会渲染,避免了不必要的循环。