百度上已经有不少的关于slot-scope的文章,但我感受都是那些之前没学好,又回头学的人,他们都使用了.Vue文件,我以为有点不适合初学者,因此我就写一篇适合初学者的。html
先抛例程:vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件之经过插槽(slot)分发内容</title>
<script src="你的vue地址,请下载最新版的"></script>
<script>
Vue.component("test-slot",{
// 插槽容许有默认内容
template:
`<div>
<strong>Error!</strong>
<slot></slot>
</div>
`,
data:function () {
return {
name:"perry"
}
}
});
// 具名插槽
Vue.component("slot-name",{
template:
`<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot ></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`
});
// 做用域插槽
Vue.component("todo-list",{
inheritAttrs:false,
props:{
todos:[Array,Object]
},
template:
`<ul>
<li v-for="todo in todos" :key="todo.id" style="display: block;" >
<slot :data="todo">{{todo.text}}</slot>
</li>
</ul>
`
});
</script>
<style>
li{
list-style: none;
display: inline-block;
font-size: 25px;
}
</style>
</head>
<body>
<div id="app">
<!--一、插槽内容 slot能够接收任何内容、代码,包括组件-->
<test-slot>Something bad happened.你是谁啊,我认识你吗</test-slot>
<test-slot>
Something bad happened.
<!--容许使用变量,但该变量必须是本做用域的才会生效,这里name的值将会是"岔道口"-->
<h3>标题{{name}}</h3>
<img src="img/flower.jfif" alt="图片没法显示">
</test-slot>
<!--二、具名插槽 slo有一个特殊的属性name,可使插槽具名-->
<slot-name>
<h3>劝学</h3>
<p>少壮不努力,老大徒伤悲</p>
<p>光阴似箭,日月如梭</p>
<template slot="header">
<ul >
<li>主页</li>
<li>关于时间</li>
<li>关于人生</li>
<li>关于将来</li>
</ul>
</template>
<p>你好啊</p>
<p slot="footer">
<p>结尾</p>
<p>粤ICP备6545646456415</p>
</p>
</slot-name>
<!--使用做用域插槽,经过slot-scope实现-->
<todo-list :todos="todos">
<template slot-scope="slotProps">
<span v-if="slotProps.data.isTrue">√</span>
{{slotProps.data.text}}
</template>
</todo-list>
<!--使用ES2015结构语法-->
<todo-list :todos="todos">
<template slot-scope="{data}">
<span v-if="data.isTrue">√</span>
{{data.text}}
</template>
</todo-list>
</div>
<script>
new Vue({
el:"#app",
data:{
name:"岔道口",
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},
],
// slotProps:""
}
})
</script>
</body>
</html>
例程中也写了普通插槽和具名插槽,这个我就不说,我就说一下做用域插槽。首先从“做用域插槽“”这个名字提及,原本你父组件的模板是没法使用到子组件模板中的数据,官网中有一句特别强调的话:父组件模板的全部东西都会在父级做用域内编译;子组件模板的全部东西都会在子级做用域内编译。这句话其实挺难理解,举个例子就知道了,app
<test-slot>spa
Something bad happened..net
<!--容许使用变量,但该变量必须是本做用域的才会生效,这里name的值将会是"岔道口"-->component
<h3>标题{{name}}</h3>htm
<img src="img/flower.jfif" alt="图片没法显示">对象
</test-slot>blog
这是我上面的例子,也就是说这里name必须是当前组件里的,不能是test-slot这个组件内部的数据,这是它做用域限制,name这个数据属于父组件的做用域,因此只能是父组件的数据。可是slot-scope的出现却实现了父组件调用子组件内部的数据,子组件的数据经过slot-scope属性传递到了父组件图片
// 做用域插槽
Vue.component("todo-list",{
inheritAttrs:false,
props:{
todos:[Array,Object]
},
template:
`<ul>
<li v-for="todo in todos" :key="todo.id" style="display: block;" >
//这里的:data=“todo”就是讲子组件todo这个数据传给了父组件
<slot :data="todo">{{todo.text}}</slot>//todo.text是默认值,父组件会把它覆盖掉
</li>
</ul>
`
});
<!--使用做用域插槽,经过slot-scope实现-->
<todo-list :todos="todos">
<template slot-scope="slotProps">
<span v-if="slotProps.data.isTrue">√</span>
{{slotProps.data.text}}
</template>
</todo-list>
使用的时候就是这样,从子组件传过来的名为data值为todo的数据将会被slot-scope接收,须要注意的是,slot-scope接收的是一个对象,这里命名为slotProps,也就是说你传过来的data将会做为slotProps的一个属性,因此须要slotProps.data才能调用到data。前面说了,data的值为todo,todo是什么呢?todo是todos遍历出来的,因此是一个对象。
new Vue({ el:"#app", data:{ name:"岔道口", 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}, ], // slotProps:"" }}); 咱们已经理解了slot-scope特性,那么他有什么运用场景呢?咱们能够试想一下,别人写好了一个组件,该组件已经封装好了,但他以为,数据的显示风格让用户本身定义,就像咱们上面,咱们但愿列表的样式由用户定义,好比我就加了一个√号。一开始最初的数据是咱们传进去的,但数据必须进过子组件处理后,写组件那我的确定但愿显示的是处理后的数据。这时候slot-scope就无比重要了。————————————————版权声明:本文为CSDN博主「perryhuan9」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接及本声明。原文连接:https://blog.csdn.net/huangyilinnuli/article/details/81239077