别再手搓DOM了!Vue3组合式API,性能优化到飞起🚀
传统DOM操作的困境
在传统的网页开发中,我们通常需要这样操作DOM:
// 传统DOM操作示例(类似demo.html中的代码)
document.getElementById('input').addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
let text = this.value;
if (text) {
let li = document.createElement('li');
li.innerHTML = '<input type="checkbox"> ' + text;
document.getElementById('todo-list').appendChild(li);
this.value = '';
}
}
});
这种做法的问题显而易见:
- 命令式:我们需要手动操作DOM元素
- 机械式:代码需要不断关注"如何修改DOM",而不是"数据如何变化"
- 性能差:频繁操作DOM会导致页面重绘重排,性能低下
Vue框架的革命性优势
Vue框架改变了我们的开发方式:不再需要思考页面的元素怎么操作,而是要思考数据是怎么变化的。Vue采用数据驱动视图的模式,当我们更新数据时,Vue会自动计算并更新视图,无需手动操作DOM。
Vue的主要优点:
- 简单:指令式语法直观易学,上手快
- 高效:响应式系统自动优化DOM更新
- 好上手:API设计友好,学习成本低
Vue3与Vue2:API的演进
Vue 2 使用的是 Options API,将数据、方法、计算属性等组织在data、methods、computed等选项中。
Vue 3 引入了 Composition API(组合式API),通过<script setup>语法,让代码组织更加灵活,特别适合大型项目。
<!-- Vue2 (Options API) -->
<script>
export default {
data() {
return {
title: 'Todos 任务清单'
}
},
methods: {
addTodo() { /* ... */ }
}
}
</script>
<!-- Vue3 (Composition API) -->
<script setup>
import { ref, computed } from 'vue'
const title = ref('Todos 任务清单')
const addTodo = () => { /* ... */ }
</script>
Composition API的优势:
- 逻辑组织更清晰:将相关功能的代码放在一起
- 代码复用性更好:更容易提取和复用逻辑
- 适合大型项目:避免了Options API中可能出现的代码分散问题
实战:Todos 任务清单
现在,让我们通过一个待办任务清单的实战案例,深入理解Vue的核心特性。
代码如下:
<template>
<div>
<h1>Todos 任务清单</h1>
<!-- 数据绑定 -->
<h2>{{title}}</h2>
<!-- 双向数据绑定 -->
<input type="text" v-model="title" @keydown.enter="addTodo">
<!-- v-if——条件渲染指令 -->
<ul v-if="todos.length">
<!-- key 作为唯一属性 -->
<li v-for="todo in todos" :key="todo.id">
<input type="checkbox" v-model="todo.done">
<span :class="{done:todo.done}">{{todo.title}}</span>
</li>
</ul>
<div v-else>
暂无计划
</div>
<div>
<input type="checkbox" v-model="allDone">
{{ active }}
/
{{ todos.length }}
</div>
</div>
</template>
<script setup>
import { ref , computed} from 'vue'
// ref 响应式数据
const title = ref('Todos 任务清单');
const todos = ref([
{
id: 1,
title: '打瓦',
done: false
},
{
id: 2,
title: '吃饭',
done: false
}
])
const active = computed(()=>{
return todos.value.filter(todo=>!todo.done).length
})
const addTodo = ()=>{
if(!title.value) return;
todos.value.push({
id:Math.random(),
title:title.value,
done:false
})
// 清空输入框
title.value = ''
}
// computed 高级技巧
const allDone = computed({
get(){
return todos.value.every(todo=>todo.done)
},
set(val){
todos.value.forEach(todo=>todo.done = val)
}
})
</script>
<style>
.done{
text-decoration: line-through;/*删除线 */
color:gray
}
</style>
1. 核心指令:v-for、v-model、v-bind
<!-- 列表渲染 -->
<ul v-if="todos.length">
<li v-for="todo in todos" :key="todo.id">
<input type="checkbox" v-model="todo.done">
<span :class="{done:todo.done}">{{todo.title}}</span>
</li>
</ul>
-
v-for:用于列表渲染,类似JavaScript的map方法v-for="todo in todos":遍历todos数组,为每个元素创建一个<li>元素:key="todo.id":为每个列表项提供唯一标识,帮助Vue高效更新DOM
-
v-model:双向数据绑定,自动同步输入框和数据v-model="todo.done":将复选框的状态与todo.done数据绑定- 当用户勾选复选框时,
todo.done的值自动更新;当todo.done更新时,复选框状态自动更新
-
v-bind:动态绑定属性(:class是v-bind:class的缩写):class="{done:todo.done}":根据todo.done的值动态应用CSS类- 当
todo.done为true时,应用done类,添加删除线效果
2. 计算属性:性能优化的关键
简单表达式的问题:
{{ todos.filter(todo => !todo.done).length }} / {{ todos.length }}
当页面其他数据变化时,这个表达式会重新计算,即使数据没有变化。这会导致不必要的性能开销。
使用computed的优化:
const active = computed(() => {
return todos.value.filter(todo => !todo.done).length
})
优化前后对比:
| 优化前(简单表达式) | 优化后(computed) |
|---|---|
{{ todos.filter(todo => !todo.done).length }} / {{ todos.length }} | {{ active }} / {{ todos.length }} |
| 每次页面更新都会重新计算 | 只有todos变化时才重新计算 |
| 性能较差,可能造成不必要的重渲染 | 通过缓存机制,性能显著提升 |
为什么性能提升这么大?
- Vue的响应式系统会追踪
active计算属性依赖的todos数据 - 只有当
todos发生变化时,才会触发active的重新计算 - 无需担心页面其他部分变化导致的重复计算
3. computed高级技巧:实现全选功能
const allDone = computed({
get() {
return todos.value.every(todo => todo.done)
},
set(val) {
todos.value.forEach(todo => todo.done = val)
}
})
这里使用了get/set属性的概念:
get:获取全选状态(所有任务是否都已完成)set:当全选框状态改变时,更新所有任务的状态
在模板中使用:
<input type="checkbox" v-model="allDone">
交互过程:
- 用户点击全选框,
v-model触发allDone的set方法 set方法将allDone的值(true或false)应用到所有任务- 所有任务的
done状态被更新 - Vue自动更新视图,显示新的任务状态
总结:Vue的核心优势
通过这个待办任务清单的案例,我们看到了Vue的核心优势:
- 简单:只需关注数据变化,无需手动操作DOM
- 高效:响应式系统自动优化更新,避免不必要的DOM操作
- 好上手:指令式语法(v-for、v-model等)直观易学
- 高性能:计算属性的缓存机制带来显著性能提升
正如Vue的官方文档所说:"Vue 是一个用于构建用户界面的渐进式框架。与其他大型框架不同,Vue 被设计为可以自底向上逐层应用。"
Vue不仅仅是一个框架,它代表了一种数据驱动视图的开发理念,让前端开发变得更加简单、高效,让开发者能够专注于业务逻辑,而不是DOM操作的细节。
通过这个简单的待办任务清单,我们已经体验了Vue的核心优势。随着对Vue的深入学习,你会发现它在构建复杂应用时的强大力量。