Skip to content

Commit 5f7cdb2

Browse files
作用域插槽,解构插槽
1 parent 802d928 commit 5f7cdb2

File tree

3 files changed

+273
-14
lines changed

3 files changed

+273
-14
lines changed

Vue-Component/README.md

Lines changed: 188 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,191 @@ var nameSlot = new Vue({
497497

498498
### 作用域插槽
499499

500-
作用域插槽是一种特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样:
500+
作用域插槽是一种特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样,说白了就是**获取本组件的数据!**
501+
502+
```html
503+
<!-- 父组件 -->
504+
<div id="scope">
505+
<child>
506+
<!--
507+
语法:v-slot:default="随意取的名字" ,default可省略,简写为v-slot="随意取的名字" -->
508+
<template v-slot="slotProps">
509+
<h1>{{slotProps.list.text}}</h1>
510+
</template>
511+
</child>
512+
</div>
513+
```
514+
515+
```js
516+
var scope = new Vue({
517+
el: "#scope",
518+
components: {
519+
child: {
520+
// 绑定到元素上的特性(v-bind:list="item")被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字。
521+
522+
// 绑定语法:v-bind:随意起的名字="需要传递的子组件数据"
523+
524+
template: `<ul>
525+
<li v-for="(item,index) in list" :key="index.id">
526+
<slot v-bind:list="item"></slot>
527+
</li>
528+
</ul>`,
529+
data() {
530+
return {
531+
list: [
532+
{
533+
id: 1,
534+
text: "javascript",
535+
},
536+
{
537+
id: 2,
538+
text: "php",
539+
},
540+
{
541+
id: 3,
542+
text: "java",
543+
},
544+
],
545+
};
546+
},
547+
},
548+
},
549+
});
550+
```
551+
552+
最终渲染结果
553+
554+
```html
555+
<ul>
556+
<li><h1>javascript</h1></li>
557+
<li><h1>php</h1></li>
558+
<li><h1>java</h1></li>
559+
</ul>
560+
```
561+
562+
### 具名插槽的作用域插槽
563+
564+
与匿名插槽同理,只需要把 default 替换成插槽的 name 值即可。
565+
566+
```html
567+
<!-- 父组件 -->
568+
<div id="scope">
569+
<child>
570+
<!--
571+
语法:v-slot:具名的名字="随意取的名字" -->
572+
<template v-slot:list="nameProps">
573+
<h1>{{nameProps.list.id}}</h1>
574+
</template>
575+
</child>
576+
</div>
577+
```
578+
579+
```js
580+
var scope = new Vue({
581+
el: "#scope",
582+
components: {
583+
child: {
584+
template: `<ul>
585+
<li v-for="(item,index) in list" :key="index.id">
586+
<slot name="list" v-bind:list="item"></slot>
587+
</li>
588+
</ul>`,
589+
data() {
590+
return {
591+
list: [
592+
{
593+
id: 1,
594+
text: "javascript",
595+
},
596+
{
597+
id: 2,
598+
text: "php",
599+
},
600+
{
601+
id: 3,
602+
text: "java",
603+
},
604+
],
605+
};
606+
},
607+
},
608+
},
609+
});
610+
```
611+
612+
最终渲染结果
613+
614+
```html
615+
<ul>
616+
<li><h1>1</h1></li>
617+
<li><h1>2</h1></li>
618+
<li><h1>3</h1></li>
619+
</ul>
620+
```
621+
622+
### 解构插槽 Prop
623+
624+
v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。所以在支持的环境下 (单文件组件或现代浏览器),你也可以使用 ES2015 解构来传入具体的插槽 prop。
625+
626+
```
627+
语法:v-slot="{ xxx }"
628+
```
629+
630+
我们来看一下结构插槽
631+
632+
```html
633+
<div id="deconstruction">
634+
<child>
635+
<!-- 解构 v-slot="{子组件定义的名字}"" -->
636+
<template v-slot="{ users }">
637+
<h1>{{users.name}}</h1>
638+
</template>
639+
</child>
640+
</div>
641+
```
642+
643+
```js
644+
var deconstruction = new Vue({
645+
el: "#deconstruction",
646+
components: {
647+
child: {
648+
template: `<div>
649+
<slot v-bind:users="user"></slot>
650+
</div>`,
651+
data() {
652+
return {
653+
user: {
654+
name: "heqi",
655+
age: 24,
656+
},
657+
};
658+
},
659+
},
660+
},
661+
});
662+
```
663+
664+
最终渲染结果
665+
666+
```html
667+
<div><h1>heqi</h1></div>
668+
```
669+
670+
相对于传统的作用域插槽,优势在于父组件不用重新自定义名称在通过对象的方式点出来,则直接沿用子组件的名称选择其键名
671+
672+
我们也可以给重命名
673+
674+
```html
675+
<div id="deconstruction">
676+
<child>
677+
<!-- 解构 v-slot="{子组件定义的名字 : 需要重命名的名字}"" -->
678+
<template v-slot="{ users : person }">
679+
<!-- 如果用之前的名字会报错如下图,需要改成重命名后的名字 -->
680+
<!-- <h1>{{users.name}}</h1> -->
681+
<h1>{{person.name}}</h1>
682+
</template>
683+
</child>
684+
</div>
685+
```
686+
687+
![img4.png](https://i.loli.net/2020/08/18/aTYoSXczbZ5qx3L.png)

Vue-Component/image/img4.png

697 KB
Loading

Vue-Component/index.html

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,26 @@ <h1>php</h1>
8484
</div>
8585

8686
<!-- slot插槽 - 作用域插槽 -->
87+
<div id="scope">
88+
<child>
89+
<template v-slot="slotProps">
90+
<h1>{{slotProps.list.text}}</h1>
91+
</template>
92+
<template v-slot:list="nameSlot">
93+
<h2>{{nameSlot.list.id}}</h2>
94+
</template>
95+
</child>
96+
</div>
97+
98+
<!-- slot插槽 - 解构插槽 -->
99+
<div id="deconstruction">
100+
<child>
101+
<!-- 解构 v-slot="{子组件定义的名字}"" -->
102+
<template v-slot="{ users : person }">
103+
<h1>{{person.name}}</h1>
104+
</template>
105+
</child>
106+
</div>
87107
</body>
88108
</html>
89109
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.1/vue.js"></script>
@@ -224,12 +244,12 @@ <h1>php</h1>
224244
components: {
225245
child: {
226246
template: `<div>
227-
<p>{{propA}}</p>
228-
<p>{{propB}}</p>
229-
<p>{{propC}}</p>
230-
<p>{{propD}}</p>
231-
<p>{{propE}}</p>
232-
</div>`,
247+
<p>{{propA}}</p>
248+
<p>{{propB}}</p>
249+
<p>{{propC}}</p>
250+
<p>{{propD}}</p>
251+
<p>{{propE}}</p>
252+
</div>`,
233253
props: {
234254
// 基础类型检测 (`null` 指允许任何类型)
235255
propA: Number,
@@ -295,9 +315,9 @@ <h1>php</h1>
295315
components: {
296316
child: {
297317
template: `<div>
298-
<h1>javascript</h1>
299-
<slot></slot>
300-
</div>`,
318+
<h1>javascript</h1>
319+
<slot></slot>
320+
</div>`,
301321
},
302322
},
303323
});
@@ -308,13 +328,65 @@ <h1>javascript</h1>
308328
components: {
309329
child: {
310330
template: ` <div>
311-
<slot name="slotname"></slot>
312-
<h1>Tom</h1>
313-
<slot></slot>
314-
</div>`,
331+
<slot name="slotname"></slot>
332+
<h1>Tom</h1>
333+
<slot></slot>
334+
</div>`,
315335
},
316336
},
317337
});
318338

319339
// slot插槽 - 作用域插槽
340+
var scope = new Vue({
341+
el: "#scope",
342+
components: {
343+
child: {
344+
// 绑定到元素上的特性(v-bind:list="list")被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字。
345+
template: `<ul>
346+
<li v-for="(item,index) in list" :key="index.id">
347+
<slot v-bind:list="item"></slot>
348+
<slot name="list" v-bind:list="item"></slot>
349+
</li>
350+
</ul>`,
351+
data() {
352+
return {
353+
list: [
354+
{
355+
id: 1,
356+
text: "javascript",
357+
},
358+
{
359+
id: 2,
360+
text: "php",
361+
},
362+
{
363+
id: 3,
364+
text: "java",
365+
},
366+
],
367+
};
368+
},
369+
},
370+
},
371+
});
372+
373+
// slot插槽 - 解构插槽
374+
var deconstruction = new Vue({
375+
el: "#deconstruction",
376+
components: {
377+
child: {
378+
template: `<div>
379+
<slot v-bind:users="user"></slot>
380+
</div>`,
381+
data() {
382+
return {
383+
user: {
384+
name: "heqi",
385+
age: 24,
386+
},
387+
};
388+
},
389+
},
390+
},
391+
});
320392
</script>

0 commit comments

Comments
 (0)