setup(props,ctx)
现在只需在script标签中添加setup,组件只需引入不用注册,属性和方法也不用返回,也不用写setup函数,也不用写export default ,甚至是自定义指令也可以在我们的template中自动获得。
调用时机
创建组件实例,然后初始化 props ,紧接着就调用setup 函数。从生命周期钩子的视角来看,它会在 beforeCreate 钩子之前被调用
注意事项:
this 在 setup() 中不可用
参数:(props,ctx)
props 作为其第一个参数,它包含父组件传递给子组件的所有信息,在子组件中用props对象来接收。也就是说,当你想用props的方式来获取父组件传递的信息,就需要使用props:{ xxx } 这种方式来接收。watchEffect 或 watch 会观察和响应 props 的更新,然而不要解构 props 对象,那样会使其失去响应性。如果想要获取响应式,推荐使用
toRefs()
和toRef()
来解构保持响应式
<template>
<div @click="sonHander">
我是子组件中的数据
</div>
</template>
<script lang="ts">
import { defineComponent,setup } from 'vue';
export default defineComponent({
name: 'NoCont',
setup(props,context){
console.log('props==>',props.mytitle); //输出的值是 undefined
function sonHander(){
context.emit('sonclick','子组件传递给父组件')
}
return {sonHander}
}
});
</script>
//输出的值是 undefined因为我们没有使用props进行接收配置。如果我们添加上接受配置,即可正确获取父组件数据
props:{
mytitle:{
type:Object
}
},
第2个参数:context { attrs, slots, emit , expose },是一个对象。
attrs: (获取当前标签上的所有属性的对象) 但是该属性是props中没有声明接收的所有的对象。 如果你使用attrs.props去获取值,同时第一个参数props中你声明了你要获取的值 则:attrs.props获取的值是undefined
注意点区分: attrs获取值是不需要props中没有声明接收。第1个参数props获取值是需要props中声明接收的
**emit:**事件分发,传递给父组件需要使用该事件)
**slots:**插槽
**expose:**显式地限制当前组件想要暴露出的属性,当父组件引入该组件的实例时,将仅能访问
expose
函数暴露出的内容。
<script>
setup(props,ctx) {
// props 我们经常用户路由跳转传输过来的值或者父子传参的数据
// ctx里面有attrs 和 slots 都是内部组件实例上对应项的代理,可以确保在更新后仍然是最新值
// ctx里面的emit我们经常用,用来进行父子组件的传参
}
</script>
//安全地解构ctx
export default {
setup(props, { attrs, slots, emit, expose }) {
...
}
}
从初始化组件到最终渲染的流程如下图所示
(1)初始化组件。
(2)创建组件实例:每个组件都独立存储相关实例信息,比如组件uid、父组件实例、组件种类等信息。
(3)设置组件实例:判断当前组件实例是否是一个有状态组件,初始化(Props、Slots),执行setup处理函数。
(4)创建渲染上下文:instance.ctx做一层proxy,对渲染上下文instance.ctx属性的访问和修改,代理到对setupState、ctx、data、props 中的数据的访问和修改。
(5)创建setup函数上下文:对setup函数参数context的处理,也就是初始化context里的四个属性。
(6)执行setup函数获取结果:获取setup函数执行结果setupResult。
(7)处理setup函数执行结果:也就是处理setup函数执行结果,比如setup的返回值。
(8)完成组件实例设置:主要实现标准化模板或者渲染函数
、兼容Vue2
。