vue3插槽用法
Opened this issue · 0 comments
前言
关于vue3的插槽用法,在2.6.0版本前,是旧用法;在2.6.0 ~ 3.0版本,新旧用法兼容;但是在vue3之后,旧用法就不支持了。因此有必要掌握新用法。
slot
这部分内容还是原来的情况,并没有新语法,写出来是为了文章内容的完整性。
在自定义组件内部,用slot
标签来表示接受的插槽内容,预留展示位置。
通过name
属性来指定该插槽的名字
<slot />
<slot name="header" />
如果没name
属性,那就是一个默认插槽了,只会有一个默认插槽。
默认插槽除了预留位置外,还起到了后备内容的作用,即如果你使用组件时,没有插槽内容的话,就会显示默认插槽的内容。
v-slot
新用法是引入了v-slot
指令,该指令只能用在template
标签上(除了下面说到的独占默认插槽缩写法外)。
首先我们要知道用插槽的两个个场景:
- 具名插槽,指定名字的插槽应用
- 插槽作用域,指定插槽的作用域
新旧用法都是围绕这两个场景来解决问题的。
具名插槽
使用组件时,v-slot
用参数就能指定插槽名了
<custom>
这是默认插槽内容
<template v-slot:header>这是header插槽内容</template>
</custom>
实际上,上面的默认插槽是简写,原本是:
<custom>
<template v-slot:default>这是默认插槽内容</tempalte>
<template v-slot:header>这是header插槽内容</template>
</custom>
这时候,对应的slot
会变换成对应的插槽内容
插槽作用域
首先要明白这个的使用场景,一个组件(记做A)是有自己的作用域的,你用这个组件的所在页面(记做B,实际上也是一个组件)也有自身的作用域。如果你在B页上用了A组件,A下有插槽,想在该插槽上执行一些操作要利用A作用域下的某个值,那么这时你就需要指定该插槽的作用域为A了,因为默认情况下,用在该插槽上的数据的作用域都是属于B的。
明白上面的背景后,接着我们要知道,如果任何人都可以随意改变组件内部的变量的话,那就失去了组件的独立性了,我们也知道vue是提倡单向改变的数据的,所以如果要指向组件的作用域里的变量的话,前提是你的组件要往外暴露这么一个“入口”,告诉别人,你允许别人在插槽上使用你内部的哪些数据,这个我们叫做插槽prop
<slot v-bind:myData="myData></slot>
如上,插槽上有一个名为myData
的prop
,值为该插槽所在组件里的作用域下的myData
变量。上面内容即告诉别人,这个组件的默认插槽上往外暴露了一个叫myData
的入口,给父组件用来引用,起到访问内部myData
变量的作用
要知道,上面的myData
不一定要相同名的,只是一般都会是而已。父组件访问的是属性上的myData
,只是值的变量名刚好也叫myData
使用v-slot
指定作用域很简单,就是该指令的值了。
<!--在B页里-->
<custom>
<template v-slot:default="scopeA">
{{scopeA.myData}}
</template>
</custom>
以上为使用方法,父组件指定了名为“scopeA”的作用域,指向custom
组件的作用域,然后引用之前暴露的myData
。默认插槽的:default
可省略
在支持es6语法的环境下,上面可以写成以下更方便
<custom>
<template v-slot="{ myData }">
{{myData}}
</template>
</custom>
独占默认插槽缩写
当你使用组件时,只用到了一个默认插槽,没有其他插槽的话(虽然官方资料上说没有其他具名插槽,但是发现只要出现不是一个插槽,包括内嵌插槽,仍然不能使用),v-slot
是可以直接写在组件上的,如
<custom>
<template v-slot="{ myData }">
<p>{{myData}}</p>
</template>
</custom>
<!--上面可缩写为:-->
<custom v-slot="{ myData }">
<p>{{myData}}</p>
</custom>
除了这种情况外,任何其他情况v-slot
都只能写在template
上。
注意上面的条件,
只用到了一个默认插槽,没有其他具名插槽的
v-slot的缩写
与v-bind
、v-on
一样,v-slot
也有缩写,用#
来表示,如
<custom>
<p #default="{ myData }">{{myData}}</p>
</custom>
要使用这种缩写,那么指令参数是不可省略的,意味着默认插槽的default
不能省略。
与旧语法的不同
简单说一下旧语法的不同点,说太多怕大家记混淆了就更惨了。
- 具名插槽:以前应用具名插槽时,用
slot="slotName"
这个属性就能指明当前代码是属于哪个插槽的了,可以用在template
或任意html标签上,但是新语法v-slot
只能用在template
标签上,指令参数为插槽名。 - 插槽作用域:以前是在插槽内容上(即用了
slot="slotName"
的标签上或默认插槽标签上)用slot-scope="scopeName"
来指明作用域,但是新语法v-slot
只能用在template
标签上,同样是值为域名。