面试题答案
一键面试1. 代码组织更灵活
- Options API:在 Vue 2 中,Options API 将不同功能逻辑分散在
data
、methods
、computed
、watch
等选项中。例如,一个包含数据获取、处理及展示的组件:
<template>
<div>
<p>{{ user.name }}</p>
<button @click="fetchUser">刷新用户</button>
</div>
</template>
<script>
export default {
data() {
return {
user: null
}
},
methods: {
async fetchUser() {
const response = await fetch('/api/user')
this.user = await response.json()
}
},
mounted() {
this.fetchUser()
}
}
</script>
-
这种组织方式在组件逻辑复杂时,不同功能的代码分散,难以维护和理解。
-
Composition API:在 Vue 3 中,Composition API 允许根据逻辑功能将代码组织在一起。以
setup
函数为例:
<template>
<div>
<p>{{ user.name }}</p>
<button @click="fetchUser">刷新用户</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const user = ref(null)
const fetchUser = async () => {
const response = await fetch('/api/user')
user.value = await response.json()
}
fetchUser()
return {
user,
fetchUser
}
}
}
</script>
- 这里通过
setup
函数将数据(user
)和相关操作(fetchUser
)组织在一个函数内,逻辑清晰,更易理解和维护。
2. 更好的逻辑复用
- Options API:复用逻辑通常通过
mixin
实现,但mixin
可能会导致命名冲突,并且混入的逻辑来源不清晰。例如:
// mixin.js
export const userMixin = {
data() {
return {
user: null
}
},
methods: {
async fetchUser() {
const response = await fetch('/api/user')
this.user = await response.json()
}
},
mounted() {
this.fetchUser()
}
}
// component.vue
<template>
<div>
<p>{{ user.name }}</p>
</div>
</template>
<script>
import { userMixin } from './mixin.js'
export default {
mixins: [userMixin]
}
</script>
-
当多个
mixin
混合时,数据和方法来源难以追踪。 -
Composition API:通过自定义
composition function
实现逻辑复用,更清晰且避免命名冲突。例如:
// useUser.js
import { ref } from 'vue'
export const useUser = () => {
const user = ref(null)
const fetchUser = async () => {
const response = await fetch('/api/user')
user.value = await response.json()
}
fetchUser()
return {
user,
fetchUser
}
}
// component.vue
<template>
<div>
<p>{{ user.name }}</p>
</div>
</template>
<script>
import { useUser } from './useUser.js'
export default {
setup() {
const { user, fetchUser } = useUser()
return {
user,
fetchUser
}
}
}
</script>
- 复用逻辑的来源一目了然,且不同
composition function
之间不会产生命名冲突。
3. ref
和 reactive
的影响
ref
:用于创建响应式的基本数据类型或对象。例如:
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">增加</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
const increment = () => {
count.value++
}
return {
count,
increment
}
}
}
</script>
-
在 Options API 中没有类似简洁创建基本类型响应式数据的方式。
ref
使得基本类型数据响应式处理更直观,在代码组织上更集中处理数据和操作。 -
reactive
:用于创建深度响应式对象。例如:
<template>
<div>
<p>{{ user.name }}</p>
<p>{{ user.age }}</p>
<button @click="updateUser">更新用户</button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const user = reactive({
name: 'John',
age: 30
})
const updateUser = () => {
user.name = 'Jane'
user.age++
}
return {
user,
updateUser
}
}
}
</script>
- 在 Options API 中使用
data
返回对象实现响应式,但reactive
更明确地标识为创建响应式对象,在代码组织上,围绕该响应式对象的操作可以紧密结合在一起,增强代码逻辑性。