Composition API 中的setup

本文详细解释了Vue3.0中的setup函数,包括其执行时机(在beforeCreate之前),返回值的处理(对象属性和方法的合并),以及注意事项,如避免在setup中使用async函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

setup

· 新的option, 所有的组合API函数都在此使用, 只在初始化时执行一次

· 函数如果返回对象, 对象中的属性或方法, 模板中可以直接使用

1.setup执行的时机

在beforeCreate之前执行(一次), 此时组件对象还没有创建

this是undefined, 不能通过this来访问data/computed/methods / props

其实所有的composition API相关回调函数中也都不可以

2.setup的返回值

 1.一般都返回一个对象: 为模板提供数据, 也就是模板中可以直接使用此对象中的所有属性/方法

2.返回对象中的属性会与data函数返回对象的属性合并成为组件对象的属性

3.返回对象中的方法会与methods中的方法合并成功组件对象的方法

4.如果有重名, setup优先

注意:

1.一般不要混合使用: methods中可以访问setup提供的属性和方法, 但在setup方法中不能访问data和methods

2.setup不能是一个async函数: 因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性数据

setup的参数:

setup(props, context) / setup(props, {attrs, slots, emit})

props: 包含props配置声明且传入了的所有属性的对象

attrs: 包含没有在props配置中声明的属性的对象, 相当于 this.$attrs

slots: 包含所有传入的插槽内容的对象, 相当于 this.$slots

 emit: 用来分发自定义事件的函数, 相当于 this.$emit

<template>
  <div style="font-size: 14px">
    <h2>了解setup</h2>
    <p>msg: {{msg}}</p>
    <button @click="fn('--')">更新</button>
    <!-- 子组件 -->
    <child :msg="msg" msg2="cba" @fn="fn"/>
  </div>
</template>

<script lang="ts">
// vue3.0版本语法
import { defineComponent, ref, } from 'vue'
import child from './child.vue'

export default defineComponent ({
  name: '父组件',
  components: {
    child
  },
  setup () {
    const msg = ref('abc')
    function fn (content: string) {
      msg.value += content
    }
    return {
      msg,
      fn
    }
  }
})
</script>

子组件:

<template>
  <div>
    <h3>{{ n }}</h3>
    <h3>{{ m }}</h3>
    <h3>msg: {{ msg }}</h3>
    <h3>msg2: {{ $attrs.msg2 }}</h3>
    <slot name="xxx"></slot>

    <button @click="update">更新</button>
  </div>
</template>

<script lang="ts">
// vue3.0版本语法
import { ref, defineComponent } from "vue";

export default defineComponent({
  name: "child",
  props: ["msg"],
  emits: ["fn"], // 可选的, 声明了更利于程序员阅读, 且可以对分发的事件数据进行校验

  data() {
    console.log("data", this);
    return {
      // n: 1
    };
  },

  beforeCreate() {
    console.log("beforeCreate", this);
  },

  methods: {
    // update () {
    //   this.n++
    //   this.m++
    // }
  },

  // setup (props, context) {
  setup(props, { attrs, emit, slots }) {
    console.log("setup", this);
    console.log(props.msg, attrs.msg2, slots, emit);
    const m = ref(2);
    const n = ref(3);
    function update() {
      // console.log('--', this)
      // this.n += 2
      // this.m += 2
      m.value += 2;
      n.value += 2;
      // 分发自定义事件
      emit("fn", "++");
    }

    return {
      m,
      n,
      update,
    };
  },
});
</script>
初始化页面效果:

点击父组件的更新按钮后的页面效果:

再点击子组件的更新按钮后的页面效果:

### Composition API 的核心概念与使用方法 Composition APIVue 3 中引入的一种新的组件逻辑组织方式,它通过 `setup` 函数来定义组件的状态、计算属性、方法等[^1]。这种方式的主要优势在于能够将相关的逻辑封装在一起,便于复用和组合,从而解决了 Options API 在复杂场景下代码分散的问题。 #### 1. 基本结构 在 Vue 3 中,使用 Composition API 的组件需要在 `setup` 函数中定义所有逻辑。`setup` 函数会在组件实例创建之前执行,并返回一个对象,该对象中的属性和方法会暴露给模板[^1]。 ```javascript import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); // 定义响应式数据 const doubleCount = computed(() => count.value * 2); // 定义计算属性 return { count, doubleCount }; // 返回的数据和方法会被暴露到模板中 } }; ``` #### 2. 状态管理 通过 `ref` 和 `reactive`,可以轻松创建响应式数据。`ref` 用于创建基本类型的数据,而 `reactive` 则用于创建对象类型的响应式数据[^1]。 ```javascript import { ref, reactive } from 'vue'; export default { setup() { const count = ref(0); // 基本类型 const state = reactive({ name: 'Vue.js' }); // 对象类型 return { count, state }; } }; ``` #### 3. 计算属性 使用 `computed` 可以定义依赖于其他响应式数据的计算属性。计算属性是惰性的,只有在其依赖的数据发生变化时才会重新计算。 ```javascript import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const doubleCount = computed(() => count.value * 2); return { count, doubleCount }; } }; ``` #### 4. 生命周期钩子 Composition API 提供了与 Options API 类似的生命周期钩子,如 `onMounted`、`onUnmounted` 等。这些钩子可以通过单独导入的方式使用。 ```javascript import { onMounted, onUnmounted } from 'vue'; export default { setup() { onMounted(() => { console.log('Component mounted'); }); onUnmounted(() => { console.log('Component unmounted'); }); return {}; } }; ``` #### 5. 监听变化 使用 `watch` 和 `watchEffect` 可以监听响应式数据的变化并执行副作用[^4]。 - `watch`:显式指定要监听的响应式数据。 - `watchEffect`:自动跟踪其内部使用的响应式数据。 ```javascript import { ref, watch, watchEffect } from 'vue'; export default { setup() { const count = ref(0); watch(count, (newValue, oldValue) => { console.log(`count changed from ${oldValue} to ${newValue}`); }); watchEffect(() => { console.log(`count is now ${count.value}`); }); return { count }; } }; ``` #### 6. 逻辑复用 Composition API 的一大优势在于能够通过自定义函数实现逻辑复用。这种复用方式比 Options API 更加灵活和直观[^1]。 ```javascript // useCounter.js import { ref } from 'vue'; export function useCounter(initialValue = 0) { const count = ref(initialValue); const increment = () => count.value++; const decrement = () => count.value--; return { count, increment, decrement }; } // 组件中使用 import { useCounter } from './useCounter'; export default { setup() { const { count, increment, decrement } = useCounter(); return { count, increment, decrement }; } }; ``` ### TypeScript 支持 Composition APITypeScript 中的表现更为出色,因为它允许开发者更直观地定义类型,避免了 Options API 中可能存在的类型推断问题[^2]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值