Vue3 Composition API 完全指南

Vue3 Composition API 完全指南

嗨,大家好,我是莫循,今天给大家分享一篇Vue3 Composition API的使用指南。

📚 目录

  1. 组合式API核心概念

  2. 与选项式API对比

  3. setup深度解析

  4. 响应式API体系

  5. 生命周期管理

  6. 逻辑复用模式

  7. 最佳实践

🌟 组合式API核心概念

定义

组合式API(Composition API)是Vue3的核心特性,它通过逻辑功能聚合高复用性解决了复杂组件的代码组织问题。主要特征:

  • 功能聚合:将同一功能的响应式数据、计算属性、方法等集中管理

  • 逻辑复用:通过自定义Hook实现跨组件逻辑复用

  • 类型支持:完美支持TypeScript类型推断

  • 渐进式:可与选项式API混合使用

解决的问题场景

问题类型 选项式API痛点 组合式API解决方案
代码组织 功能分散在多个配置项 按功能聚合逻辑
大型组件维护 超过1000行代码难以维护 拆分为多个逻辑单元
逻辑复用 Mixins导致命名冲突 可组合函数
TypeScript支持 类型推断困难 天然支持类型推导

🔧 setup深度解析

基础用法

js 复制代码
// 传统写法
export default {
  setup(props, context) {
    const count = ref(0)
    const double = computed(() => count.value * 2)
    
    function increment() {
      count.value++
    }

    return { 
      count,
      double,
      increment
    }
  }
}

// <script setup> 语法糖(推荐)
<script setup>
import { ref, computed } from 'vue'

const count = ref(0)
const double = computed(() => count.value * 2)

function increment() {
  count.value++
}
</script>

生命周期映射表

选项式API 组合式API 执行时机
beforeCreate - 在setup之前执行
created - 在setup之前执行
beforeMount onBeforeMount 挂载开始前
mounted onMounted DOM挂载完成
beforeUpdate onBeforeUpdate 数据变更导致DOM更新前
updated onUpdated DOM更新完成后
beforeUnmount onBeforeUnmount 组件卸载前
unmounted onUnmounted 组件卸载完成

Props深度处理

js 复制代码
// 组件声明
export default {
  props: {
    userInfo: {
      type: Object,
      required: true,
      validator: (v) => v.age > 18
    }
  },
  setup(props) {
    // 安全解构方案
    const { userInfo } = toRefs(props)
    const userName = computed(() => userInfo.value.name)
    
    // 可选prop处理
    const theme = toRef(props, 'theme') // 等效props.theme || default
    
    return { userName }
  }
}

Context完整解析

js 复制代码
setup(props, { 
  attrs,     // 未声明的属性(相当于this.$attrs)
  slots,     // 插槽对象(相当于this.$slots)
  emit,      // 事件发射器(相当于this.$emit)
  expose     // 暴露公共API
}) {
  // 暴露指定方法
  expose({
    resetData: () => { /*...*/ }
  })

  // 事件发射示例
  const handleClick = () => {
    emit('custom-event', { data: 123 })
  }

  return { handleClick }
}

⚡ 响应式API体系

核心API对比

API 适用场景 深度响应 示例
ref 基本类型/对象引用 浅层 const num = ref(0)
reactive 复杂对象 深层 const obj = reactive({})
shallowRef 大型对象性能优化 浅层 const bigData = shallowRef({})
readonly 不可变数据 深层 const copy = readonly(original)
computed 派生数据 自动 const sum = computed(() => a+b)
watch 复杂侦听 可配置 watch(source, callback, { deep: true })

响应式转换原理

js 复制代码
// ref实现原理简化版
function myRef(value) {
  const wrapper = {
    get value() {
      track(wrapper, 'value') // 依赖追踪
      return value
    },
    set value(newVal) {
      value = newVal
      trigger(wrapper, 'value') // 触发更新
    }
  }
  return wrapper
}

🧩 逻辑复用模式

自定义Hook示例

js 复制代码
// useCounter.js
import { ref, computed } from 'vue'

export default function useCounter(initialValue = 0) {
  const count = ref(initialValue)
  
  const double = computed(() => count.value * 2)
  
  function increment() {
    count.value++
  }

  function reset() {
    count.value = initialValue
  }

  return {
    count,
    double,
    increment,
    reset
  }
}

// 组件使用
<script setup>
import useCounter from './useCounter'

const { count, increment } = useCounter(10)
</script>

与Mixin对比优势

维度 Mixin 组合式函数
命名冲突 容易发生 变量作用域隔离
隐式依赖 需要查看mixin源码 显式参数传递
类型支持 困难 完美支持TS
逻辑复用 整个mixin 按需引用
可测试性 困难 独立测试

🏆 最佳实践

代码组织规范

js 复制代码
<script setup>
// 1. 外部导入
import { useRouter } from 'vue-router'

// 2. Props定义
const props = defineProps({
  title: String
})

// 3. 事件定义
const emit = defineEmits(['submit'])

// 4. 组合式函数
const { data } = useFetch('/api')

// 5. 响应式状态
const searchQuery = ref('')

// 6. 计算属性
const filteredList = computed(() => {
  return list.value.filter(item => item.includes(searchQuery.value))
})

// 7. 生命周期
onMounted(() => {
  console.log('组件已挂载')
})

// 8. 方法定义
function handleSubmit() {
  emit('submit', { data })
}

// 9. 暴露API
defineExpose({
  reset: () => { searchQuery.value = '' }
})
</script>

性能优化技巧

  1. 响应式优化

    js 复制代码
    // 批量更新
    import { nextTick } from 'vue'
    
    const updateData = () => {
      data.value = bigData
      nextTick(() => {
        // DOM更新后操作
      })
    }
  2. 侦听器优化

    js 复制代码
    watch(
      () => props.list, 
      (newVal) => {
        // 处理逻辑
      },
      { deep: true, immediate: true }
    )
  3. 内存管理

    js 复制代码
    onUnmounted(() => {
      // 清除定时器/事件监听
    })
  4. 组件分割

    js 复制代码
    // 大型组件拆分为多个<script setup>文件
    import ChartSection from './ChartSection.vue'
    import DataTable from './DataTable.vue'
相关推荐
Qrun30 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp30 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.1 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front8 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰8 小时前
纯flex布局来写瀑布流
前端·javascript·css