vue3-setup

156 阅读2分钟

setup

1.执行时间

  • 在beforeCreate前执行一次,此时组件还未被创建
  • this为undefined,不能通过this访问data,methods,props

返回值

如果 setup 返回一个对象,那么该对象的 property 以及传递给 setup 的 props 参数中的 property 就都可以在模板中访问到

<template>
  <div>{{ collectionName }}: {{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    props: {
      collectionName: String
    },
    setup(props) {
      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      // 暴露给 template
      return {
        readersNumber,
        book
      }
    }
  }
</script>

注意,从 setup 返回的 refs 在模板中访问时是被自动浅解包的,因此不应在模板中使用 .value

setup 还可以返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态:


import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // 请注意这里我们需要显式使用 ref 的 value
    return () => h('div', [readersNumber.value, book.title])
  }
}

返回一个渲染函数将阻止我们返回任何其它的东西。从内部来说这不应该成为一个问题,但当我们想要将这个组件的方法通过模板 ref 暴露给父组件时就不一样了。

我们可以通过调用 expose 来解决这个问题,给它传递一个对象,其中定义的 property 将可以被外部组件实例访问:

import { h, ref } from 'vue'
export default {
  setup(props, { expose }) {
    const count = ref(0)
    const increment = () => ++count.value

    expose({
      increment
    })

    return () => h('div', count.value)
  }
}

这个 increment 方法现在将可以通过父组件的模板 ref 访问。

参数

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

setup 函数中的第一个参数是 props。正如在一个标准组件中所期望的那样,setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。

export default {
  props: {
    title: String
  },
  setup(props) {
    console.log(props.title)
  }
}

因为props是响应式的,所以不能使用ES6结构,它会消除 prop 的响应性。 如果需要解构 prop,可以在 setup 函数中使用 toRefs 函数来完成此操作:

import { toRefs } from 'vue'

setup(props) {
  const { title } = toRefs(props)

  console.log(title.value)
}

emit:用来分发自定义事件,相当于this.$emit()

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

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