虽说Vue3已经在性能方面做了很大的改进,但这仅是框架层面的,在项目开发中不管是个人习惯,还是方法选择,都会对应用的性能造成影响。下面简单的罗列了一些优化建议:
尽可能使用计算属性
计算属性默认是缓存的,只有当它的依赖发生变化时,它才会重新计算。因此,尽量不要在模板中使用方法,因为每次渲染时都会调用方法,这可能会导致不必要的性能开销。
<template>
<div>
<p>{{ fullName }}</p>
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
return {
fullName,
};
},
};
</script>
使用v-if而不是v-show
虽然v-show看起来很方便,但它实际上并不移除元素,只是简单地切换它的display CSS属性。如果你有一个比较重的元素并且知道它只会显示一次,最好使用v-if。
<template>
<div>
<button @click="toggle">Toggle</button>
<p v-if="showElement">This is a visible element.</p>
<!-- <p v-show="showElement">This is a visible element.</p> -->
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const showElement = ref(true);
function toggle() {
showElement.value = !showElement.value;
}
return {
toggle,
showElement,
};
},
};
</script>
使用key属性来替换列表
当Vue渲染列表时,它会尝试尽可能少地改变DOM。如果你的列表中有复杂的元素,或者元素的顺序可能会变化,最好给每个元素加上一个唯一的key。
<template>
<div>
<button @click="addItem">Add Item</button>
<ul>
<li v-for="(item, index) in items" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const items = ref(['Item 1', 'Item 2']);
function addItem() {
items.value.push(`Item ${items.value.length + 1}`);
}
return {
items,
addItem,
};
},
};
</script>
避免在v-for中使用v-if
如果你在v-for循环中使用v-if,Vue将无法进行一些优化。你应该尽可能在循环外部处理过滤和映射。
<template>
<div>
<ul>
<li v-for="item in filteredItems" :key="item.id">{{ item.name }}</li>
</ul>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const items = ref([
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Cherry' },
]);
const filteredItems = computed(() => items.value.filter((item) => item.name !== 'Banana'));
return {
filteredItems,
};
},
};
</script>
不要过度使用插槽
虽然插槽非常强大,可以让组件更加灵活,但如果过度使用,可能会导致性能问题。插槽会在渲染时生成新的树,这可能比直接在组件内部渲染内容要慢。
<!-- 父组件 -->
<template>
<child-component>
<template #default="{ data }">
<p>{{ data }}</p>
</template>
</child-component>
</template>
<!-- 子组件 -->
<template>
<slot :data="someData"></slot>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const someData = ref('Some data');
return {
someData,
};
},
};
</script>
合理使用watch和watchEffect
确保你真正需要的时候才使用它们。因为它们可能会引起额外的渲染和计算。
import { ref, watch } from 'vue';
const count = ref(0);
// 仅在真正需要时使用 watch
watch(count, (newVal, oldVal) => {
console.log(`Count changed from ${oldVal} to ${newVal}`);
});
// 避免不必要的 watchEffect
watchEffect(() => {
console.log(`Count is now ${count.value}`);
});
不要滥用全局状态管理
如果你有一个全局的状态管理库(比如Vuex),并且你的组件可以从远端获取数据,那么请考虑是否真的需要全局状态管理。如果没有必要,尝试将状态保持在组件内部。
const localState = ref({
count: 0,
});
function increment() {
localState.value.count++;
}
return {
localState,
increment,
};
评论区