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>