天下无坑

天下无坑


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** &lt;slot name="插槽名" :age="[1,2,3]" :sex="[0,1]"&gt;&lt;/slot&gt;; :**父页面中寻找slot的template** &lt;template #插槽名="{age,sex}"&gt;&lt;/template&gt;; if (是否找到?) then (找到) :获取子组件所有prop的数据集合; :用父页面中的template渲染; else (没找到) :用子组件slot内的html作为template渲染(如有); note right Vue.component("datagrid",{ props:{ data:null }, template:` &lt;table&gt; &lt;thead&gt; &lt;slot name="headslot"&gt;&lt;/slot&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr v-for="itemV in data"&gt; &lt;slot name="bodyslot" :item="itemV"&gt; &lt;!- - 子组件中如果slot带有默认内容,且有渲染数据 - -&gt; &lt;!- - 需要使用itemV, 而不是props名item - -&gt; {{itemV.text}} &lt;/slot&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; ` }); end note endif stop </code></pre> <ul> <li><strong>理解图二</strong></li> </ul> <pre><code class="language-plantuml">parent&lt;-child.vue:检查获取子组件的slot parent-&gt;child.vue:用template标签重写slot模板 parent&lt;-child.vue:从slot中取出所有props数据,整合为一个对象 parent-&gt;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=&quot;user&quot;指令的集合</strong></li> </ul> <pre><code class="language-html">&lt;todo-list&gt; &lt;template v-slot:todo="slotProps"&gt; {{slotProps.user.firstName}} &lt;/template&gt; &lt;/todo-list&gt; //多个props可用对象解构或改名,如写成: v-slot:todo="{user,name}" v-slot:todo="{user:uid,name}"</code></pre> <h3>子组件</h3> <pre><code class="language-html"> &lt;slot name="todo" :user="userV" :test="testV"&gt; {{ userV.lastName }} &lt;/slot&gt; 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">&lt;!doctype html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;title&gt;vue slot-scope&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;div id="app"&gt; &lt;datagrid :data="todos"&gt; &lt;template #headslot&gt; &lt;tr&gt; &lt;td&gt;id&lt;/td&gt; &lt;td&gt;text&lt;/td&gt; &lt;td&gt;isTrue&lt;/td&gt; &lt;/tr&gt; &lt;/template&gt; &lt;template #bodyslot="slotProps"&gt; &lt;!--slotProps是slot上的props的数据集合--&gt; &lt;td&gt;{{slotProps.item.id}}&lt;/td&gt; &lt;td&gt;{{slotProps.item.text}}&lt;/td&gt; &lt;td&gt;{{slotProps.item.isTrue}}&lt;/td&gt; &lt;/template&gt; &lt;!-- 另一种写法,加花括号,列出props名--&gt; &lt;!--&lt;template #bodyslot="{item}"&gt; &lt;td&gt;{{item.id}}&lt;/td&gt; &lt;td&gt;{{item.text}}&lt;/td&gt; &lt;td&gt;{{item.isTrue}}&lt;/td&gt; &lt;/template&gt; --&gt; &lt;/datagrid&gt; &lt;/div&gt; &lt;script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"&gt;&lt;/script&gt; &lt;!-- &lt;script src=../static/vue.js&gt;&lt;/script&gt; --&gt; &lt;script&gt; Vue.component("datagrid",{ props:{ data:null }, template:` &lt;table&gt; &lt;thead&gt; &lt;slot name="headslot"&gt;&lt;/slot&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr v-for="itemV in data"&gt; &lt;slot name="bodyslot" :item="itemV"&gt; &lt;!-- 如果slot带有默认内容,且有渲染数据 --&gt; &lt;!-- 需要使用itemV, 而不是props名item --&gt; {{itemV.text}} &lt;/slot&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; ` }); 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}, ] } }); &lt;/script&gt; &lt;/body&gt; &lt;/html&gt; </code></pre>

页面列表

ITEM_HTML