Vue 3 组合式 API(Composition API)教程

Vue 3 引入了 Composition API,它提供了一种更灵活、可复用的方式来组织组件逻辑,特别适用于大型项目。相较于 Vue 2 的 选项式 API,组合式 API 提供了更好的逻辑复用性和代码组织性。


1. 组合式 API 的核心函数

API功能
setup()组件的入口,初始化数据、方法
ref()创建响应式数据
reactive()创建响应式对象
computed()计算属性
watch()监听数据变化
watchEffect()立即执行并监听
provide() / inject()父子组件共享数据
onMounted()组件挂载后执行
onUnmounted()组件卸载时执行

2. setup() 基础

Vue 3 组件中的 setup() 是组合式 API 的入口。它在组件创建时执行,并返回模板可以使用的数据和方法。

示例:基本的 setup()

<template>
  <h2>{{ message }}</h2>
</template>

<script>
export default {
  setup() {
    const message = "Hello Vue 3!";
    return { message };
  }
};
</script>

setup() 返回的 message 直接在模板中使用。


3. 响应式数据 ref()reactive()

Vue 3 提供了 ref()reactive() 创建响应式数据。

3.1 ref():适用于基本数据类型

<script>
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);

    const increment = () => {
      count.value++; // 访问 `.value`
    };

    return { count, increment };
  }
};
</script>

<template>
  <p>计数: {{ count }}</p>
  <button @click="increment">增加</button>
</template>

ref() 需要通过 .value 访问数据。


3.2 reactive():适用于对象

<script>
import { reactive } from 'vue';

export default {
  setup() {
    const person = reactive({
      name: "张三",
      age: 25
    });

    const updateAge = () => {
      person.age++;
    };

    return { person, updateAge };
  }
};
</script>

<template>
  <p>姓名: {{ person.name }}</p>
  <p>年龄: {{ person.age }}</p>
  <button @click="updateAge">增加年龄</button>
</template>

reactive() 直接修改对象属性,而不需要 .value


4. 计算属性 computed()

computed() 用于创建依赖其他数据的计算属性。

<script>
import { ref, computed } from 'vue';

export default {
  setup() {
    const price = ref(100);
    const quantity = ref(2);

    const totalPrice = computed(() => price.value * quantity.value);

    return { price, quantity, totalPrice };
  }
};
</script>

<template>
  <p>单价: {{ price }}</p>
  <p>数量: {{ quantity }}</p>
  <p>总价: {{ totalPrice }}</p>
</template>

computed() 会自动更新,不需要手动调用。


5. 监听数据变化 watch()watchEffect()

5.1 watch()

watch() 监听某个数据的变化,并执行回调。

<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    const name = ref("Vue");

    watch(name, (newValue, oldValue) => {
      console.log(`姓名从 ${oldValue} 变为 ${newValue}`);
    });

    return { name };
  }
};
</script>

<template>
  <input v-model="name" placeholder="输入新名字">
</template>

只有 name 变化时,watch() 才会触发。


5.2 watchEffect()

watchEffect() 立即执行,并自动收集依赖。

<script>
import { ref, watchEffect } from 'vue';

export default {
  setup() {
    const count = ref(0);

    watchEffect(() => {
      console.log(`计数更新: ${count.value}`);
    });

    return { count };
  }
};
</script>

<template>
  <button @click="count++">增加: {{ count }}</button>
</template>

watchEffect() 立即执行一次,并在 count 变化时再次触发。


6. 生命周期钩子

组合式 API 采用 onMounted() 等函数来替代 Vue 2 的生命周期钩子。

Vue 2Vue 3
beforeCreatesetup() 里执行初始化代码
createdsetup() 里执行逻辑
mountedonMounted()
beforeUnmountonBeforeUnmount()
unmountedonUnmounted()

示例:使用 onMounted()

<script>
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const message = ref("页面加载中...");

    onMounted(() => {
      message.value = "页面已加载";
    });

    return { message };
  }
};
</script>

<template>
  <h2>{{ message }}</h2>
</template>

onMounted() 组件挂载时执行。


7. 父子组件通信

7.1 defineProps() 接收父组件数据

<!-- 子组件 Child.vue -->
<template>
  <p>姓名: {{ name }}</p>
</template>

<script>
export default {
  props: ["name"]
};
</script>

<!-- 父组件 Parent.vue -->
<template>
  <Child :name="userName" />
</template>

<script>
import { ref } from 'vue';
import Child from './Child.vue';

export default {
  setup() {
    const userName = ref("小明");
    return { userName };
  },
  components: { Child }
};
</script>


7.2 emit() 触发事件

<!-- 子组件 -->
<template>
  <button @click="sendMessage">发送消息</button>
</template>

<script>
import { defineEmits } from 'vue';

export default {
  setup() {
    const emit = defineEmits(["customEvent"]);

    const sendMessage = () => {
      emit("customEvent", "你好,父组件!");
    };

    return { sendMessage };
  }
};
</script>

<!-- 父组件 -->
<template>
  <Child @customEvent="handleEvent" />
</template>

<script>
import Child from "./Child.vue";

export default {
  setup() {
    const handleEvent = (message) => {
      console.log("收到消息:", message);
    };
    return { handleEvent };
  },
  components: { Child }
};
</script>


8. 总结

Vue 3 组合式 API 提供了更好的代码组织方式:

  • ref() 适用于基本数据类型
  • reactive() 适用于对象
  • computed() 处理计算属性
  • watch()watchEffect() 监听数据
  • onMounted() 等钩子处理生命周期
  • defineProps()emit() 处理组件通信

在大型项目中,使用 Composition API 让代码更清晰、更易维护! 🚀