523 vue组件化高级 插槽slot:slot基本使用,具名插槽,编译作用域,作用域插槽
为什么使用slot
如何封装这类组件:slot
slot基本使用
01-slot-插槽的基本使用.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--
1.插槽的基本使用 <slot></slot>
2.插槽的默认值 <slot>button</slot>
3.如果有多个值, 同时放入到组件进行替换时, 一起作为替换元素
-->
<div id="app">
<cpn></cpn>
<cpn><span>哈哈哈</span></cpn>
<cpn><i>嘿嘿嘿</i></cpn>
<cpn>
<i>呵呵呵</i>
<div>我是div元素</div>
<p>我是p元素</p>
</cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>我是组件111</h2>
<p>我是组件222</p>
<slot><button>按钮333</button></slot>
<!--<button>按钮</button>-->
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>
</body>
</html>
具名插槽slot
02-slot-具名插槽的使用.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn>
<span slot="left">返回</span>
<span slot="center">搜索框</span>
<span slot="right">登录</span>
</cpn>
<cpn><button slot="left">返回</button></cpn>
</div>
<template id="cpn">
<div>
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>
</body>
</html>
编译作用域
03-什么是编译的作用域.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译 -->
<div id="app">
<!-- 使用isShow,会看看isShow是在哪个模板里,会把cpn当做div看待,这里是在app模板里,会使用app父组件的isShow、names -->
<cpn v-show="isShow"></cpn>
<cpn v-for="item in names">
<div>{{item}}</div>
</cpn>
</div>
<!-- 这里是在cpn模板里,会使用cpn子组件的isShow -->
<template id="cpn">
<div>
<h3>我是子组件</h3>
<button v-show="isShow">按钮</button>
<slot></slot>
<hr>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isShow: true,
names: [11, 22, 33]
},
components: {
cpn: {
template: '#cpn',
data() {
return {
isShow: false,
names: [44, 55, 66]
}
}
},
}
})
</script>
</body>
</html>
作用域插槽
作用域插槽:准备
作用域插槽:使用
04-作用于插槽的案例.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn>
<!--目的是获取子组件中的pLanguages-->
<template slot-scope="slot">
<!--<span v-for="item in slot.data"> - {{item}}</span>-->
<span>{{slot.data.join(' - ')}}</span>
</template>
</cpn>
<cpn>
<!--目的是获取子组件中的pLanguages-->
<template slot-scope="slot">
<!--<span v-for="item in slot.data">{{item}} * </span>-->
<span>{{slot.data.join(' * ')}}</span>
</template>
</cpn>
<!--<cpn></cpn>-->
</div>
<template id="cpn">
<div>
<slot :data="pLanguages">
<ul>
<li v-for="item in pLanguages">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data() {
return {
pLanguages: ['JavaScript', 'C++', 'Java', 'C#', 'Python', 'Go', 'Swift']
}
}
}
}
})
</script>
</body>
</html>
补充的案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<cpn>
<!-- 不显示 -->
<div>222</div>
<!-- 显示 -->
<div slot-scope="scope">
<div>{{scope}}</div>
<div>{{scope.shuzi}}</div>
<div>{{scope.yuyan}}</div>
</div>
<!-- 不显示 -->
<div>333</div>
</cpn>
<hr>
<cpn>
<!-- 结论:使用slot-scope时,用最后一个slot-scope替换模板中的slot -->
<!-- 不显示 -->
<div>555</div>
<!-- 不显示 -->
<div slot-scope="scope">
<div>{{scope.shuzi}}</div>
</div>
<!-- 显示 -->
<div slot-scope="scope">
<div>{{scope}}</div>
<div>{{scope.shuzi}}</div>
<div>{{scope.yuyan}}</div>
</div>
</cpn>
</div>
<template id="cpn">
<div>
<h5>cpn组件</h5>
<slot :shuzi="num" :yuyan="pLanguages"></slot>
</div>
</template>
<script src="./vue.js"></script>
<!-- <script src="./node_modules/vuex/dist/vuex.js"></script> -->
<script>
Vue.component('cpn', {
template: '#cpn',
data() {
return {
num: 111,
pLanguages: ['JavaScript', 'C++', 'Java', 'C#', 'Python', 'Go', 'Swift']
}
},
})
const vm = new Vue({
el: '#app',
data: {
msg: ''
}
})
</script>
</body>
</html>