vue插槽slot理解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue插槽slot理解相关的知识,希望对你有一定的参考价值。
参考技术Avue的插槽用法,官方文档写的内容个人感觉有点乱,不自己梳理一下的话,使用的时候也容易懵逼,下面是我对vue插槽使用的理解:
slot概念源于web components规范草案(地址: https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md )
vue官网关于插槽的文档中,第一句话即说明了vue的slot插槽设计源于web components,具体内容可以自行了解,这里只说vue框架下slot的用法。
概念: slot可将 父组件 在 子组件标签里 写的 content 渲染到子组件 对应 的地方
先说通用性用法,再说特殊情况会让人比较容易接受。这里以最具通用性的写法,以 具名插槽 的写法为例子展开
父组件中:
子组件中
渲染结果:
父组件template标签上的v-slot指令与子组件的slot标签的name属性,通过绑定一样的值,形成一一对应的关系。
父组件中:
子组件中:
注意,上述例子中,都有v-slot绑定default属性的情况,这里需要说明下,vue中的插槽用法,default属性的模板和插槽存在特殊的对应情况,而比较容易混乱的点就在这里,这也是vue官网插槽文档让人看得很蒙圈的地方,因为官网并没有给我们分区域的讲述通用情况和特殊情况,而是穿插着讲,让人容易理不清楚关系。
子组件的slot标签中的值可以写入内容,这部分内容会在没有对应的模板内容的时候,作为默认值展示
父组件
子组件
渲染结果
具名插槽的写法具备通用性,学会了具名插槽写法,那么插槽的用法已经能够掌握8成了。下面将展开的是插槽中的特殊对应关系
------------ 默认的default模板和插槽 -----------
父组件
子组件情形1
子组件情形2
渲染结果都是
由于两种情形中都没有name属性是test的插槽,所以渲染结果中没有出现test模板里的内容。
上述例子中涵盖了2个知识点,首先通过子组件情形2能得到渲染结果,可以得出一个结论:
default模板的内容必定会渲染到defalut插槽中,所以,通过子组件情形1能得出渲染结果,也可以得出一个结论:
最后还需要注意,模板和插槽的对应关系是1对多的关系。即同名模板只能有一个,但是同名插槽可以有无数个,会同时渲染
以上内容涵盖了9成的插槽用法,足以满足日常使用。下面将要对插槽作用域问题展开讲解
很简单
1.模板内容一般都是在父组件,所以模板内容的作用域自然是父组件的作用域,父组件的动态内容基本上取自父组件的变量或函数,但是有特殊情况可以读取到子组件传出来的值,第3点会讲。
2.同理,插槽一般都是在子组件,所以作用域自然在子组件,比如子组件插槽中放入了动态内容作为默认值,该动态内容必定取值于子组件的变量,也只能读取到子组件的变量和函数
3.特殊情况,父组件可以用子组件传出来的值,这个时候会有写法上的变化:
子组件
父组件正常调用
父组件解构对象调用
渲染结果
v-slot指令可以变成缩写的写法,类似v-bind缩写为:,v-on缩写为@,v-slot可以缩写为#
例如
等价于
这里出现了v-slot指令直接绑定在子组件标签名上的情况,使用场景是,当前模板只有一个default模板,并且需要获取子组件传来的值时,才能这样使用。
不接受传值的情况,会报错
非default模板,也会报错
子组件
父组件
除了default模板外,还存在其他模板时,也会报错
以上基本总结了插槽的所有用法,其中第5点和第8点的特殊情况都是针对default模板的,这一点一定要分清楚。
还有1点很关键的知识,即default模板和插槽不算是具名模板和插槽,第8点的非default模板会报错的原因,即该特殊情况不支持具名模板和插槽。但是default模板和插槽在平时写的时候可以用具名模板和插槽的写法,也可以用省略的写法,即第5点描述的情况。
vue中的插槽slot理解
本篇文章参考赛冷思的个人博客
1.函数默认传参
在我们写js函数我们的可能会给他们一个默认的参数,写法是
function show(age,name){
var age = age || 20;
var name = name || 张三;
console.log(age,name);
}
show(); // 20,张三
show(18,"命名") // 18,明明
如果用户不传入参数,那么会输出默认值,如果用户传入,会输出传入的值,这种写法很灵活
vue中的组件,也可以有默认的模板,当我们调用一个组件,啥都不传时,显示我们定义的默认模板,当我们传了自定义模板时,就应该使用我们自定义的模板,来替换默认模板,那么,今天说的slot,其实它就是实现的这个功能,可以理解为函数的传参。下面以类似官方的例子进行解释。
现在有个一个模板 child
<div>
<h2>我是子组件的标题</h2>
<slot>
<p>当父组件调用我时,没有传自定义内容时,我就会显示了,如果传了自定义内容,我就不显示了。</p>
</slot>
</div>
slot中的就是默认参数,如果我们不传入参数
<child></child>就会被渲染成
<div>
<h2>我是子组件的标题</h2>
<p>当父组件调用我时,没有传自定义内容时,我就会显示了,如果传了自定义内容,我就不显示了。</p>
</div>
如果我们传入参数
<child><p>这是我自定义的内容,覆盖子组件slot中的内容</p></child>渲染为
<div>
<h2>我是子组件的标题</h2>
<p>这是我自定义的内容,覆盖子组件slot中的内容</p>
</div>
我们可以看到child中的元素会把模板中的内容改变,就好像我们传入的参数一样,所有理解为默认模板
但是可以看到,这种方式过于粗暴,并且只能定义一块默认内容,不是很方便,所以官方说了,slot还提供了一个具名功能,意思就是,在子组件定义slot时,加个标识,在父组件调用,自定义内容时,也加上标识,这样就实现了可以在任意地方定义默认内容,下面有请具名slot,其实就是给slot起个名字
<div class="container">
<header>
<slot name="header"><h1>默认header</h1></slot>
</header>
<main>
<slot><p>默认main</p></slot>
</main>
<footer>
<slot name="footer"><p>默认footer</p></slot>
</footer>
</div>
上面的是子组件,我们给每一个slot一个name属性,如果是默认值的话,name是没有什么作用的,在传参时,我们可以让child中的元素,加上slot属性
<div>
<child>
<h1 slot=‘header‘>自定义标题</h1>
<p slot=‘footer‘>自定义底部</p>
<p>自定义main</p>
</child>
</div>
所以,我们的child最后就被渲染成了
<div>
<div class="container">
<header>
<h1>自定义标题</h1>
</header>
<main>
<p>自定义main</p>
</main>
<footer>
<p>自定义底部</p>
</footer>
</div>
</div>
在子组件定义slot加个name属性值,在父组件调用时,加上slot属性,值就是子组件中slot的name属性值,这样就会自动定位到对应的slot中,就实现了多个地方定义默认内容。
以上是关于vue插槽slot理解的主要内容,如果未能解决你的问题,请参考以下文章