开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情
为了通过组合式API获得该模板引用,我们需要声明一个同名的ref(ref的值为null,声明的名字与模板的ref同名)如下所示:
如果不使用 <script setup>
,须确保从setup()返回ref(这种写法的话必须得有返回值):
注意:你只可以在组件挂载后才能访问模板引用。如果你想在模板中的表达式上访问input,在初次渲染时会是null,这是因为在初次渲染前这个元素还不存在。
如果你需要侦听一个模板引用ref的变化,确保考虑到其值为null的情况:
v-for中的模板引用
当在v-for中使用模板引用时,对应的ref中包含的值是一个数组,它将在元素被挂载后包含对应整个列表的所有的元素。
得到结果的格式:
注意:ref数组并不保证与源数组相同的顺序。
函数模板引用
除了使用字符串值做名字,ref 属性还可以绑定为一个函数,会在每次组件更新时都被调用。该函数会收到元素引用作为其第一个参数:
注意:我们这里需要使用动态:ref绑定才能够传入一个函数。当绑定的元素被卸载时,函数也会被调用一次,此时的el参数会是null,也可以绑定一个组件方法而不是内联函数。
组件上的ref
模板引用也可以被用在一个子组件上,这种情况下引用中获得的值是组件实例:
如果一个子组件使用的是选项式API或没有使用<script setup>
,被引用的组件实例和该子组件的this完全一致,这意味着父组件对子组件的每一个属性和方法都有完全的访问权。这使得在父组件和子组件之间创建紧密耦合的实现细节变得很容易,当然也因此,应该只在绝对需要时才使用组件引用。大多数情况下,你应该首先使用标准的props
和emit
接口来实现父子组件交互。
有一个例外的情况,使用了<script setup>
的组件是默认私有的:一个父组件无法访问到一个使用了<script setup>
子组件中的任何东西,除非子组件在其中通过defineExpose宏显示暴露(父组件可以访问子组件在宏显示暴露的内容,在<script setup>
的前提下):
当父组件通过模板引用获取到了该组件的实例时,得到的实例类型为{a:number,b:number}ref都会自动解包,和一般的实例一样。
传递props
props是一种特别的属性,如果想传递给一个组件数据,可以在组件上声明注册,在组件的props列表上声明它,要用到defineProps宏:
defineProps是一个仅<script>
中可用的编译宏命令,并不需要显示地导入。生命的props会自动暴露给模板。defineProps会返回一个对象,其中包含了可以传递给组件的所有props
如果你没有使用<script setup>
,props必须以props选项的方式声明,props对象会作为setup()函数的第一个参数被传入。
props两种写法:
第一种:没有使用<script setup>
的写法如下:
父组件:
子组件:
第二种:使用<script setup>
写法(不用显式导入,下面的例子导入了):
defineProps数组格式单纯接值,对象格式可以设置传递过来的数据的格式和必填项等。
具体的props的校验
注意:defin()宏中的参数不可以访问<script setup>
中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。
组合式API监听事件
我们可以通过defineEmits宏来声明需要抛出的事件
父组件:
子组件第一种写法:
在
<script setup>
,模式下,需要引入defineEmits,然后创建一个常见作为它的返回值,这个返回值就是触发方法,在事件里用返回来触发自定义事件,这样就能监听到,
第二种写法:不写返回值,在模板里通过$emit可以直接访问defineEmits的方法。如下:
如果你没有在使用<script setup>
,你可以通过emits选项定义组件会抛出的事件,你可以从setup()函数的第二个参数,即setup上下文对象上访问到emit函数。
defineEmits()宏不能在子函数中使用,必须直接放置在<script setup>
的顶级作用域下,不能放在组建的某个函数里面。
defineProps和defineEmits他们两个只能用在顶级作用域下:
如果用的是选项式,那么还是要用选项式的方法:
声明触发的时间
组件要触发的事件可以显式地通过defineEmits()宏来声明。
我们在<template>
中使用的$emit方法不能在组件的<script setup>
部分中使用,但defineEmits()会返回一个相同作用的函数供我们使用:
这个emits选项还支持对象语法,它允许我们对触发事件的参数进行验证: