编译作用域
在使用作用域插槽之前我们要了解编译作用域的概念
我们先来考虑一下下面的代码能否渲染出来
text 代码:
在组件my-cpn中我们使用了v-show指令
isShow包含在组件中,也包含在vue实列中
<body>
<div id="app">
<my-cpn v-show="isShow"></my-cpn>
</div>
<template id="cpn">
<div>
<div>这是子组件</div>
</div>
</template>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
const app = new Vue({
el:'#app',
data:{
isShow:true
},
components:{
myCpn:{
template:'#cpn',
data(){
return{
isShow:false
}
}
}
}
})
</script>
- 在代码中我们在vue实列中有一个isShow值为true,子组件中也有一个isShow值为false
- 那么组件中使用的isShow是它自己的还是vue实列的呢?
运行结果:
这是子组件
很明显,v-show="isShow"为true,my-cpn组件使用的是vue实列中的isShow
原因:
text 代码: <div id="app">
<my-cpn v-show="isShow"></my-cpn>
</div>
vue决定isShow的值时,会去该组件的父组件中查找有没有isShow
在代码中,my-cpn的父组件是vue实列,而vue实列中有isShow
所以
取的是vue实列中的值。
作用域插槽的使用
作用:父组件修改子组件插槽,内容有子组件提供
为了更好的理解,我们先提一个需求
- 子组件中有一组数据:plangusges:['java','js','c','c++']
- 需要在多个界面展示,有的以列表形式,有点水平展示。
- 内容在子组件,展示形式有父组件决定
子组件模板中默认显示方式为列表显示
text 代码: <template id="cpn">
<div>
<slot name="test" :data="plangusges">
<ul>
<li v-for="item in plangusges">{{item}}</li>
</ul>
</slot>
</div>
</template>
<div id="app">
<!-- 子组件默认展示形式 -->
<cpn></cpn>
</div>
运行结果
- java
- js
- c
- c++
父组件修改插槽内容展示形式
text 代码: <cpn>
<template v-slot:mysolt>
<span v-for="item in plangusges">{{item}}-</span>
</template>
</cpn>
这个代码是错的,因为plangusges的作用域是vue实列,但在vue实列中是没有plangusges的。
正确方式
在插槽中使用v-bind将plangusges绑定到一个属性上(属性名随意),这里将plangusges绑定到data上。
<slot name="mysolt" :data="plangusges">
<ul>
<li v-for="item in plangusges">{{item}}</li>
</ul>
</slot>
代码中将plangusges绑定到属性data上,这种属性被称为插槽prop
我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字
用法:v-solt:插槽的name="自定义插槽prop的名字"
<div id="app">
<!-- 子组件默认展示形式 -->
<cpn></cpn>
<!-- 父组件修改子组件的展示形式 -->
<cpn>
<template v-slot:mysolt="solt">
<span v-for="item in solt.data">{{item}}-</span>
</template>
</cpn>
</div>
定义了插槽prop名字后,就可以使用它获取在插槽中绑定的数据
{{solt.data}}
完整代码
text 代码:<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<!-- 子组件默认展示形式 -->
<cpn></cpn>
<!-- 父组件修改子组件的展示形式 -->
<cpn>
<template v-slot:test="solt">
<span v-for="item in solt.data">{{item}}-</span>
</template>
</cpn>
</div>
<!-- 定义template模板 -->
<template id="cpn">
<div>
<slot name="test" :data="plangusges">
<ul>
<li v-for="item in plangusges">{{item}}</li>
</ul>
</slot>
</div>
</template>
</body>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
const app = new Vue({
el:'#app',
data:{
},
components:{
// 注册子组件
cpn:{
template:'#cpn',
data(){
return{
plangusges:['java','js','c','c++']
}
},
}
}
})
</script>
</body>
</html>
运行结果
- java
- js
- c
- c++
java-js-c-c++-