首页 技术 正文
技术 2022年11月19日
0 收藏 302 点赞 4,366 浏览 4427 个字

插槽的作用

   相信看过前一篇组件化开发后,你对组件化开发有了新的认识。

   插槽是干什么的呢?它其实是配合组件一起使用的,让一个组件能够更加的灵活多变,如下图所示,你可以将组件当作一块电脑主板,将插槽当作主板上的插槽,你可以随意的更换该主板上的零件。

  

   常见的应用场景,如淘宝的导航条:

  

  

  

   其实他们大体框架都是一样的,只是内容不同罢了。我们就可以将这个导航条定义为一个组件,而内容不同的地方都定义为一个插槽,到了不同的场景更换不同插槽即可。

匿名插槽

   使用<slot>定义插槽,当父组件模板中引用子组件时,可向该插槽插入内容,如下所示:

  1. 一个组件中最多只能拥有一个匿名插槽,它其实也叫默认插槽
  2. 每个插槽都可以有默认值

  

<body><div id="app">
<navigation>
<span>这是导航</span>
</navigation>
</div><template id="navigation">
<main>
<slot>没有内容时显示我</slot>
</main>
</template><script src="./vue.js"></script>
<script> Vue.component("navigation", {
template: "#navigation",
}) const app = new Vue({
el: "#app",
})
</script></body>

具名插槽

   实际开发中使用最多的还是具名插槽,给每个<slot>添加一个name属性。

   在插入内容时,指定slot属性为<slot>name属性进行一一插入即可。

   如下所示,定义了三种不同的搜索框,都是用的同一个组件:

  

<style>
@font-face {
font-family: 'iconfont'; /* project id 1953712 */
src: url('//at.alicdn.com/t/font_1953712_uiyayrse2ul.eot');
src: url('//at.alicdn.com/t/font_1953712_uiyayrse2ul.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_1953712_uiyayrse2ul.woff2') format('woff2'),
url('//at.alicdn.com/t/font_1953712_uiyayrse2ul.woff') format('woff'),
url('//at.alicdn.com/t/font_1953712_uiyayrse2ul.ttf') format('truetype'),
url('//at.alicdn.com/t/font_1953712_uiyayrse2ul.svg#iconfont') format('svg');
} .iconfont {
font-family: "iconfont";
font-size: 16px;
font-style: normal;
} i {
flex-grow: 2;
text-align: center;
} * {
padding: 0;
margin: 0;
box-sizing: border-box;
} nav {
width: 100%;
background-color: rgba(255, 162, 109, 0.8);
padding: 10px;
margin-bottom: 20px;
} .navigation {
display: inline-flex;
justify-content: space-around;
align-items: center;
width: 100%;
} input {
flex-grow: 6;
border-radius: 3rem;
text-align: center;
outline: none;
}</style>
<body><div id="app">
<!-- 第一个个导航条,中间用默认的input框 -->
<nav>
<navigation class="navigation">
<!-- 插入时,指定slot属性 -->
<i class="iconfont" slot="left" :style="{fontSize:'2rem'}"></i>
<i class="iconfont" slot="right" :style="{fontSize:'2rem'}"></i>
</navigation>
</nav><!-- 第二个导航条,不需要默认的input框,所以用div填充 -->
<nav style="background-color: aliceblue">
<navigation class="navigation">
<i class="iconfont" slot="left" :style="{fontSize:'2rem'}"></i>
<div slot="mid" style="width: 70%;text-align: center">双十一狂欢夜</div>
<i class="iconfont" slot="right" :style="{fontSize:'2rem'}"></i>
</navigation>
</nav><!-- 第三个导航条,不需要默认的input框,所以用div填充 -->
<nav style="background-color: #ffaad8">
<navigation class="navigation">
<i class="iconfont" slot="left" :style="{fontSize:'2rem'}"></i>
<div slot="mid" style="width: 70%;text-align: center">我的资料</div>
<i class="iconfont" slot="right" :style="{fontSize:'2rem'}"></i>
</navigation>
</nav></div><template id="navigation">
<main>
<!-- 给插槽取名 name属性-->
<slot name="left"></slot>
<slot name="mid"><input type="text" placeholder="输入你的搜索项" :style="{height:'2rem'}"></slot>
<slot name="right"></slot>
</main>
</template><script src="./vue.js"></script>
<script> Vue.component("navigation", {
template: "#navigation",
}) const app = new Vue({
el: "#app",
})
</script></body>

编译作用域

   编译作用域的意思是,在那个组件的模板中,渲染时的数据就查找那个组件。

   如下所示,父组件和子组件都有一个变量show,同时子组件中拥有一个插槽,将插槽插入子组件时用了v-show指令,那么这个被插入的元素会去找子组件的show还是找父组件的show呢?

   答案是父组件,因为插入插槽的元素是书写在父组件中的。

  

<body><div id="app">
<cpn>
<span slot="cpn-slot" v-show="show">引用父组件的show</span>
</cpn>
</div><!-- 子组件模板 -->
<template id="cpn-template">
<div>
<span v-show="show">引用子组件的show</span>
<slot name="cpn-slot"></slot>
</div>
</template><script src="./vue.js"></script>
<script>
var cpn = {
template: "#cpn-template",
data() {
return {
show: false,
}
}
}
const app = new Vue({
el: "#app",
data: {
show: true,
},
components: { // Vue实例内部进行注册
cpn,
},
})
</script>
</body>

作用域插槽

   作用域插槽使用较少,它核心理念就是用父组件来渲染子组件。

   如下代码中出现一个问题,我们如果直接进行渲染,就把代码写死了,要想改变样式那么所有引用该子组件的地方样式都会改变:

  

<body>
<div id="app">
<cpn :user-msg="msg"></cpn>
</div><!-- 子组件模板 -->
<template id="cpn-template">
<div>
<ul>
<li v-for="row in userMsg">{{row}}</li>
</ul>
</div>
</template><script src="./vue.js"></script>
<script>
var cpn = {
template: "#cpn-template",
props: ["userMsg",],
} const app = new Vue({
el: "#app",
data: {
msg: {
id: 1,
name: "yunya",
age: 18,
}
},
components: {
cpn,
}
})
</script>
</body>

   此时就可以使用作用域插槽,由父组件来渲染子组件。

   使用作用域插槽遵循三个点:

  1.必须使用DOM不识别的标签,如template进行接收子组件插槽属性

  2.接收子组件插槽属性的属性是scope

  3.scope是一个对象

   以下是渲染结果,由父组件渲染子组件,给他加粗:

  

<body>
<div id="app">
<cpn :user-msg="msg">
<template slot="message" scope="v">
<ul>
<li><b>{{v.field}}</b></li>
</ul>
</template>
</cpn>
</div><!-- 子组件模板 -->
<template id="cpn-template">
<div>
<slot name="message" v-for="row in userMsg" :field="row"></slot>
</div>
</template><script src="./vue.js"></script>
<script>
var cpn = {
template: "#cpn-template",
props: ["userMsg",],
} const app = new Vue({
el: "#app",
data: {
msg: {
id: 1,
name: "yunya",
age: 18,
}
},
components: {
cpn,
}
})
</script>
</body>

  再配一张图吧,看看每次的v是长什么样子:

  

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,000
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,512
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,358
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,141
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,771
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,849