slot之作用域插槽 理解
<blockquote>
<p>作用域插槽主要应用场景是循环结构
作用域插槽: 子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)
在父页面使用template标签对子组件的slot插槽进行重写
<code>slot标签</code>,<code>template标签</code>用于传递/接收插槽的<code>name</code>和<code>props</code>,不影响最终的html元素输出</p>
</blockquote>
<ul>
<li><strong>理解图一</strong></li>
</ul>
<pre><code class="language-plantuml">start
:**子组件中寻找作用域slot**
<slot name="插槽名" :age="[1,2,3]" :sex="[0,1]"></slot>;
:**父页面中寻找slot的template**
<template #插槽名="{age,sex}"></template>;
if (是否找到?) then (找到)
:获取子组件所有prop的数据集合;
:用父页面中的template渲染;
else (没找到)
:用子组件slot内的html作为template渲染(如有);
note right
Vue.component("datagrid",{
props:{
data:null
},
template:`
<table>
<thead>
<slot name="headslot"></slot>
</thead>
<tbody>
<tr v-for="itemV in data">
<slot name="bodyslot" :item="itemV">
<!- - 子组件中如果slot带有默认内容,且有渲染数据 - ->
<!- - 需要使用itemV, 而不是props名item - ->
{{itemV.text}}
</slot>
</tr>
</tbody>
</table>
`
});
end note
endif
stop
</code></pre>
<ul>
<li><strong>理解图二</strong></li>
</ul>
<pre><code class="language-plantuml">parent<-child.vue:检查获取子组件的slot
parent->child.vue:用template标签重写slot模板
parent<-child.vue:从slot中取出所有props数据,整合为一个对象
parent->child.vue:用得到的props对象渲染template</code></pre>
<h3>父页面</h3>
<ul>
<li><strong><code>slotProps</code> 可以随意命名</strong></li>
<li><strong><code>slotProps</code> 接收的是子组件slot标签上props的集合,即所有v-bind:user="user"指令的集合</strong></li>
</ul>
<pre><code class="language-html"><todo-list>
<template v-slot:todo="slotProps">
{{slotProps.user.firstName}}
</template>
</todo-list>
//多个props可用对象解构或改名,如写成:
v-slot:todo="{user,name}"
v-slot:todo="{user:uid,name}"</code></pre>
<h3>子组件</h3>
<pre><code class="language-html"> <slot name="todo" :user="userV" :test="testV">
{{ userV.lastName }}
</slot>
data() {
return {
userV:{
lastName:"Zhang",
firstName:"yue"
},
testV:[1,2,3,4]
}
},
// {{ userV.lastName }}是默认数据 v-slot:todo
// 当父页面没有(="slotProps") 时显示 Zhang
// 显示yue
</code></pre>
<h3>完整实例及注释</h3>
<pre><code class="language-html"><!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue slot-scope</title>
</head>
<body>
<div id="app">
<datagrid :data="todos">
<template #headslot>
<tr>
<td>id</td>
<td>text</td>
<td>isTrue</td>
</tr>
</template>
<template #bodyslot="slotProps">
<!--slotProps是slot上的props的数据集合-->
<td>{{slotProps.item.id}}</td>
<td>{{slotProps.item.text}}</td>
<td>{{slotProps.item.isTrue}}</td>
</template>
<!-- 另一种写法,加花括号,列出props名-->
<!--<template #bodyslot="{item}">
<td>{{item.id}}</td>
<td>{{item.text}}</td>
<td>{{item.isTrue}}</td>
</template>
-->
</datagrid>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<!-- <script src=../static/vue.js></script> -->
<script>
Vue.component("datagrid",{
props:{
data:null
},
template:`
<table>
<thead>
<slot name="headslot"></slot>
</thead>
<tbody>
<tr v-for="itemV in data">
<slot name="bodyslot" :item="itemV">
<!-- 如果slot带有默认内容,且有渲染数据 -->
<!-- 需要使用itemV, 而不是props名item -->
{{itemV.text}}
</slot>
</tr>
</tbody>
</table>
`
});
var vm = new Vue({
el:"#app",
data:{
todos:[
{text:"A",id:1,isTrue:true},
{text:"B",id:2,isTrue:true},
{text:"C",id:3,isTrue:false},
{text:"D",id:4,isTrue:true},
]
}
});
</script>
</body>
</html>
</code></pre>