1. 设计理念的差异
-
Vue 2 的 Options API :
基于"选项式"设计,将组件逻辑按照功能(如
data、methods、computed、watch、生命周期钩子等)拆分为不同的选项对象,所有逻辑通过this关联到组件实例。优点是结构清晰,适合简单组件;但复杂组件中,同一业务逻辑可能分散在多个选项中(如一个表单验证逻辑可能涉及
data、methods、watch),维护成本较高。 -
<script setup>:基于 Vue 3 推出的组合式 API(Composition API) ,通过"逻辑组合"的方式组织代码,允许将相关的逻辑(如数据、方法、副作用)聚合在一起,而非按选项拆分。
简化了组合式 API 的写法(无需手动返回变量、自动暴露给模板等)
2、实例对比
以下通过"计数器"和"用户信息展示"两个例子,直观对比两者的写法差异。
例 1:基础计数器(简单逻辑)
Vue 2 Options API 写法:
vue
<template>
<div>
<p>计数:{{ count }}</p>
<button @click="increment">+1</button>
</div>
</template>
<script>
export default {
// 响应式数据
data() {
return {
count: 0
}
},
// 方法
methods: {
increment() {
this.count++ // 通过 this 访问数据
}
},
// 生命周期
mounted() {
console.log('组件挂载完成,初始计数:', this.count)
}
}
</script>
Vue 3 <script setup> 写法:
vue
<template>
<div>
<p>计数:{{ count }}</p>
<button @click="increment">+1</button>
</div>
</template>
<script setup>
// 导入响应式 API
import { ref, onMounted } from 'vue'
// 响应式数据(替代 data)
const count = ref(0)
// 方法(直接定义,无需包裹在 methods 中)
const increment = () => {
count.value++ // 通过 .value 访问 ref 数据
}
// 生命周期(替代 mounted 选项)
onMounted(() => {
console.log('组件挂载完成,初始计数:', count.value)
})
</script>
核心差异:
- Options API 中数据和方法需放在固定选项中,通过
this关联; <script setup>中直接定义变量和函数,通过ref等 API 创建响应式数据,生命周期通过导入的钩子函数实现。
例 2:用户信息展示(含计算属性和 props)
Vue 2 Options API 写法:
vue
<template>
<div>
<p>用户名:{{ fullName }}</p>
<p>年龄:{{ age >= 18 ? '成年' : '未成年' }}</p>
</div>
</template>
<script>
export default {
// 接收父组件传参
props: {
firstName: String,
lastName: String,
age: Number
},
// 计算属性
computed: {
fullName() {
return `${this.firstName} ${this.lastName}` // 依赖 props
}
},
// 监听数据变化
watch: {
age(newVal) {
console.log('年龄变化:', newVal)
}
}
}
</script>
Vue 3 <script setup> 写法:
vue
<template>
<div>
<p>用户名:{{ fullName }}</p>
<p>年龄:{{ age >= 18 ? '成年' : '未成年' }}</p>
</div>
</template>
<script setup>
import { computed, watch } from 'vue'
// 接收父组件传参(替代 props 选项)
const props = defineProps({
firstName: String,
lastName: String,
age: Number
})
// 计算属性(替代 computed 选项)
const fullName = computed(() => {
return `${props.firstName} ${props.lastName}` // 直接访问 props
})
// 监听(替代 watch 选项)
watch(
() => props.age,
(newVal) => {
console.log('年龄变化:', newVal)
}
)
</script>