# 1. slot-插槽的基本使用 ​ 我们在使用组件的时候有时候希望,在组件内部定制化内容,例如京东这样。 ![](https://cdn.jsdelivr.net/gh/krislinzhao/IMGcloud/img/20200516083523.png) ![](https://cdn.jsdelivr.net/gh/krislinzhao/IMGcloud/img/20200516083549.png) 这两个都是导航栏,组件的思想是可以复用的,把这个导航栏看做一个组件。 这个组件都可以分成三个部分,左边中间右边,如果可以分割组件,就可以定制化组件内容了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!-- 父组件 -->
<div id="app">

<cpn></cpn>
<cpn>
<span style="color:red;">这是插槽内容222</span>
</cpn>
<cpn>
<i style="color:red;">这是插槽内容333</i>
</cpn>
<cpn></cpn>

</div>

<!-- 插槽的基本使用使用<slot></slot> -->
<!-- 子组件 -->
<template id="cpn">

<div>
<div>
&#123;&#123;message&#125;&#125;
</div>
<!-- 插槽默认值 -->
<slot><button>button</button></slot>
</div>
</template>

<script src="../js/vue.js"></script>

<script>
const cpn = {
template: "#cpn",
data() {
return {
message: "我是子组件"
}
},
}
const app = new Vue({
el: "#app",
data() {
return {
message: "我是父组件消息"
}
},
components: {
cpn
},
})
</script>
> 简单使用插槽,定义template时候使用`slot`
1
2
3
4
5
6
7
8
9
10
<!-- 子组件 -->
<template id="cpn">
<div>
<div>
&#123;&#123;message&#125;&#125;
</div>
<!-- 插槽默认值 -->
<slot><button>button</button></slot>
</div>
</template>
> 插槽可以使用默认值,``就是插槽的默认值。
1
2
<cpn></cpn>
<cpn><span style="color:red;">这是插槽内容222</span></cpn>
> 使用插槽,`这是插槽内容222`将替换插槽的默认值 上述代码结果如图所示 ![](https://cdn.jsdelivr.net/gh/krislinzhao/IMGcloud/img/20200516083936.png) > 替换了两次插槽,两次未替换显示默认的button。 > > 如果想实现组件分成三部分就可以使用三个``来填充插槽了。 # 2. slot-具名插槽的使用 ​ 具名插槽,就是可以让插槽按指定的顺序填充,而没有具名的插槽是按照你填充的顺序排列的,而具名插槽可以自定义排列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!-- 父组件 -->
<div id="app">

<cpn>
<span>具名插槽</span>
<span slot="left">这是左边具名插槽</span>
<!-- 新语法 -->
<template v-slot:center>这是中间具名插槽</template>
<!-- 新语法缩写 -->
<template #right>这是右边具名插槽</template>


</cpn>


</div>

<!-- 插槽的基本使用使用<slot></slot> -->
<!-- 子组件 -->
<template id="cpn">

<div>

<slot name="left">左边</slot>
<slot name="center">中间</slot>
<slot name="right">右边</slot>
<slot>没有具名的插槽</slot>
</div>
</template>

<script src="../js/vue.js"></script>

<script>
const cpn = {
template: "#cpn",
data() {
return {
message: "我是子组件"
}
},
}
const app = new Vue({
el: "#app",
data() {
return {
message: "我是父组件消息"
}
},
components: {
cpn
},
})
</script>
> 如图所示 ![](https://cdn.jsdelivr.net/gh/krislinzhao/IMGcloud/img/20200516084157.png) > 没有具名的插槽排在最后,因为在定义组件的时候,排在了最后,如果有多个按顺序排列。具名插槽按照自定义的顺序排列。 > 定义具名插槽,使用`name`属性,给插槽定义一个名字。
1
2
3
4
5
6
7
8
9
10
<!-- 插槽的基本使用使用<slot></slot> -->
<!-- 子组件模板 -->
<template id="cpn">
<div>
<slot name="left">左边</slot>
<slot name="center">中间</slot>
<slot name="right">右边</slot>
<slot>没有具名的插槽</slot>
</div>
</template>
> 使用具名插槽,在自定义组件标签内使用`slot="left"`,插入指定插槽
1
2
3
4
5
6
7
8
9
10
11
<!-- 父组件 -->
<div id="app">
<cpn>
<span>具名插槽</span>
<span slot="left">这是左边具名插槽</span>
<!-- 新语法 -->
<template v-slot:center>这是中间具名插槽</template>
<!-- 新语法缩写 -->
<template #right>这是右边具名插槽</template>
</cpn>
</div>
> 注意:此处有是三种写法,获取指定插槽。 # 3. 编译的作用域 ​ 前面说过组件都有自己的作用域,自己组件的作用在自己组件内。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>编译的作用域</title>
</head>
<body>
<!-- 父组件 -->
<div id="app">
<!-- 使用的vue实例作用域的isShow -->
<cpn v-show="isShow"></cpn>
</div>
<!-- 插槽的基本使用使用<slot></slot> -->
<!-- 子组件 -->
<template id="cpn">
<div>
<h2>我是子组件</h2>
<p>哈哈哈</p>
<!-- 组件作用域,使用的子组件的作用域 -->
<button v-show="isShow"></button>
</div>
</template>

<script src="../js/vue.js"></script>

<script>
const cpn = {
template: "#cpn",
data() {
return {
isShwo:false
}
},
}
const app = new Vue({
el: "#app",
data() {
return {
message: "我是父组件消息",
isShow:true
}
},
components: {
cpn
},
})
</script>
</body>

</html>
结果如下 ![](https://cdn.jsdelivr.net/gh/krislinzhao/IMGcloud/img/20200516084606.png) > 子组件使用的是子组件的isShow,子组件为false,所以button没显示,被隐藏。 # 4. 作用域插槽案例 ​ 父组件替换插槽的标签,但是内容是由子组件来提供。 ​ 当组件需要在多个父组件多个界面展示的时候,将内容放在子组件插槽中,父组件只需要告诉子组件使用什么方式展示界面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>作用域插槽案例</title>
</head>

<body>


<!-- 父组件 -->
<div id="app">
<cpn></cpn>
<!-- 目的是获取子组件数据 -->
<cpn>
<!-- 2.5以下必须使用template -->
<template slot-scope="slot">
<!-- <span v-for="(item, index) in slot.data" :key="index">&#123;&#123;item&#125;&#125;-</span> -->
<span>&#123;&#123;slot.data.join(' - ')&#125;&#125;</span>
</template>
</cpn>
<cpn>
<!-- 2.5以下必须使用template -->
<template slot-scope="slot">
<!-- <span v-for="(item, index) in slot.data" :key="index">&#123;&#123;item&#125;&#125;*</span> -->
<span>&#123;&#123;slot.data.join(' * ')&#125;&#125;</span>
</template>
</cpn>
</div>

<!-- 插槽的基本使用使用<slot></slot> -->
<!-- 子组件 -->
<template id="cpn">

<div>
<slot :data="pLanguage">
<ul>
<li v-for="(item, index) in pLanguage" :key="index">&#123;&#123;item&#125;&#125;</li>
</ul>
</slot>

</div>
</template>

<script src="../js/vue.js"></script>

<script>
const cpn = {
template: "#cpn",
data() {
return {
isShwo:false,
pLanguage:['JavaScript','Java','C++','C']
}
},
}
const app = new Vue({
el: "#app",
data() {
return {
isShow:true
}
},
components: {
cpn
},
})
</script>
</body>

</html>
> 组件中使用`slot-scope="slot"`**(2.6.0已经废弃)**给插槽属性命名,在通过`slot`调用绑定在插槽上的属性。也可以使用`v-slot="slot"`。 ![](https://cdn.jsdelivr.net/gh/krislinzhao/IMGcloud/img/20200516084957.png)