Vue3 setup 的使用细节
-
setup执行的时机
- 在beforeCreate之前执行(一次), 此时组件对象还没有创建
- 不用使用this , this是undefined, 不能通过this来访问data/computed/methods / props
- 其实所有的composition API相关回调函数中也都不可以
-
setup的返回值
-
一般都返回一个对象: 为模板提供数据, 也就是模板中可以直接使用此对象中的所有属性/方法
-
返回对象中的属性会与data函数返回对象的属性合并成为组件对象的属性
-
返回对象中的方法会与methods中的方法合并成功组件对象的方法
-
如果有重名, setup优先
-
注意:
一般不要混合使用: methods中可以访问setup提供的属性和方法, 但在setup方法中不能访问data和methods
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> <h2>App</h2> <p>msg: {{msg}}</p> <button @click="fn('--')">更新</button> <child :msg="msg" msg2="cba" @fn="fn"/> </template> <script lang="ts"> import { reactive, ref, } from 'vue' import child from './child.vue' export default { 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"> 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>