MST

星途 面试题库

面试题:Vue 中 Composition API 如何增强代码组织能力

请阐述在 Vue 2 与 Vue 3 中,使用 Composition API 相较于 Options API 是怎样增强代码组织能力的,举例说明如 setup 函数、ref 和 reactive 的使用对代码组织产生的具体影响。
35.4万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

1. 代码组织更灵活

  • Options API:在 Vue 2 中,Options API 将不同功能逻辑分散在 datamethodscomputedwatch 等选项中。例如,一个包含数据获取、处理及展示的组件:
<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. refreactive 的影响

  • 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 更明确地标识为创建响应式对象,在代码组织上,围绕该响应式对象的操作可以紧密结合在一起,增强代码逻辑性。