setup
- vue3中的一个新的配置项,值为一个函数
- 组件中运用到的所有数据、方法等等,都要配置在setup中
- setup函数的返回值有两种:
- 返回对象(常用):在模板中可以直接使用setup返回对象中的属性、方法等
- 渲染函数(极少使用):自定义渲染内容
// 模板中可以直接使用setup返回对象中的属性、方法等 <template> <div>{{name}}</div> <div>{{age}}</div> <div @click="setInfo">{{name}}</div> </template> import { ref } from 'vue' export default { name: 'App', setup() { // ref()函数是用于配置响应式数据,后面详细说明 const name = ref('张三') const age = ref(18) function setInfo () { // xxx.value:为了响应式改变数据,后面详细说明 name.value = '李四' age.value = 20 } // 返回对象中的属性、方法 return { name, age, setInfo } } }
- 注意点:
- 不要与vue2中的配置(methods、data、cpmputed)等混用
- setup不能是一个async函数,否则return返回值为一个promise,导致模板中无法读取return中的属性
setup使用注意点
- setup的执行顺序在beforeCreate之间,在setup中this的值为undefined
- setup函数有两个参数:props和context
setup参数之props
- props:值为对象,包含了组件外部传递过来,且组件内已经声明接收了的属性
- 在setup内不存在this,因此需要通过props来获取外部组件传来的参数
// 父组件 <template> <div></div> // 在父组件中注册使用的子组件,往子组件中传递数据data <Son :message="person.name"></Son> </template> import {reactive} from 'vue' export default { name: 'App', setup () { const person = reactive({ name: ['熊大', '熊二'] }) return { person } } } // 子组件 <template> <div>{{}}</div> </template> export default { name: 'Son', // 对父组件传过来的值,用props进行声明再使用 props: ['message'] setup (props) { // 通过props参数来获取父组件传来的参数message console.log(props.message) } }
setup参数之context
- context是一个上下文对象,其中包括attrs,emit,slots三个属性
- attrs:值为对象,包含:组件外部传递过来,但在组件内没有在props中声明的属性,相当于vue2中的this.$attrs
// 父组件 <template> <div></div> // 在父组件中注册使用的子组件,往子组件中传递数据 <Son :message="person.name" :age="person.age"></Son> </template> import {reactive} from 'vue' export default { name: 'App', setup () { const person = reactive({ name: ['熊大', '熊二'] age: 3 }) return { person } } } // 子组件 <template> <div>{{}}</div> </template> export default { name: 'Son', // 对父组件传过来的值,用props进行声明再使用,没有对age进行声明 props: ['message'] setup (props, context) { // context.attrs是一个对象,包含未被声明的age属性 console.log(context.attrs) } }
- emit(重点):用于发射自定义事件,相当于vue2中的this.$emit()
// 父组件 <template> <div></div> // 在父组件中接收子组件发射的自定义事件 <Son @sendInfo="getInfoData"></Son> </template> export default { name: 'App', setup () { function getInfoData (value) { console.log(value) } return { getInfoData } } } // 子组件 <template> <div @click="send"></div> </template> import {reactive} from 'vue' export default { name: 'Son', // 通过emits属性声明该组件内发射了哪些自定义事件 emits: ['sendInfo'] setup (props, context) { const person = reactive({ name: ['熊大', '熊二'] }) function send () { context.emit('sendInfo', person.name) } return { person, send } } }
- slots:值为对象,包含的属性为收到的插槽内容,相当于vue2中的this.$slots
// 父组件 <template> <div> // 使用插槽,在父组件中定义需要在子组件使用的插槽内容 <Son> // 具名插槽,指定在子组件中name为qwe的插槽使用 <template v-slot:qwe> <div>123456</div> </template> </Son> </div> </template> // 子组件 <template> <slot name="qwe"></slot> </template> export default { name: 'Son', setup (props, context) { // 值为对象,包含的属性为收到的插槽内容qwe console.log(context.slots) } }
- attrs:值为对象,包含:组件外部传递过来,但在组件内没有在props中声明的属性,相当于vue2中的this.$attrs