Vuejs学习笔记(二)-13.插槽作用域
一、什么是编译作用域
官方准则:父组件模板的所有内容都会在父级作用域内编辑,子组件模板所有内容会在子级作用域内编译。
举个例子,在父组件Vue实例内定义一个变量 isShow=true,在子组件内也定义一个变量isShow=false,现在在父组件模板内的子组件中使用使用isShow,那么现在用的是哪一个值?按照官方准则,在父组件模板中用的就是父组件Vue实例中的变量,所以isShow=true
代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>04 编译作用域</title> 6 </head> 7 <body> 8 <div id="app"> 9 <h2>{{ message }}</h2> 10 <cpn1 v-show="isShow"></cpn1> 11 </div> 12 13 <!--div id='app'中的isShow会去APP对应的VUE实例中查找--> 14 15 <template id="cpn1"> 16 <div v-show="isShow"> 17 <h2>我是子组件1</h2> 18 </div> 19 </template> 20 <script src="../js/vue.js"></script> 21 <script> 22 const cpn1 = { 23 template: '#cpn1', 24 data(){ 25 return { 26 isShow:false 27 } 28 } 29 } 30 31 const app = new Vue({ 32 el: '#app', 33 data: { 34 message: 'hello', 35 isShow: true 36 }, 37 components: { 38 cpn1 39 } 40 }) 41 </script> 42 </body> 43 </html>
界面如下:
子组件在界面显示
二、作用域插槽
用途:1.父组件替换插槽的标签,但是内容是由子组件提供的。
2.使用子组件提供的数据,但是展示方式由父组件来设置。
人话:1.父组件使用了多个子组件,但是父组件不希望已同样的方式展示子组件,希望每个组件展示数据不一样。
解决方案:1.使用插槽,父组件在调用子组件时,可以在子组件内部插槽使用父组件系统的样式
2.子组件需要将子组件的data传递给父组件。
2.1 未使用作用域插槽时,子组件的样式是相同的:
代码如下:
1 <!-- 2 @author:invoker 3 @project:project_lianxi 4 @file: 05-作用域插槽.html 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/7/5 13:15 8 @version: html5 9 --> 10 11 <!DOCTYPE html> 12 <html lang="en"> 13 <head> 14 <meta charset="UTF-8"> 15 <title>05-作用域插槽</title> 16 </head> 17 <body> 18 <div id="app"> 19 <h2>{{ message }}</h2> 20 <cpn1></cpn1> 21 <cpn1></cpn1> 22 <cpn1></cpn1> 23 </div> 24 25 <template id="cpn1"> 26 <div> 27 <h2>我是子组件1</h2> 28 <slot> 29 <ul> 30 <li v-for="item in carList">{{item}}</li> 31 </ul> 32 </slot> 33 </div> 34 </template> 35 <script src="../js/vue.js"></script> 36 <script> 37 const cpn1 = { 38 template: '#cpn1', 39 data(){ 40 return{ 41 carList:['AE86','GR86','WRX','WRX STI','丰田86'] 42 } 43 } 44 } 45 46 const app = new Vue({ 47 el: '#app', 48 data: { 49 message: 'hello' 50 }, 51 components: { 52 cpn1 53 } 54 }) 55 </script> 56 </body> 57 </html>
2.2 使用作用域插槽解决此问题
代码如下:
1 <!-- 2 @author:invoker 3 @project:project_lianxi 4 @file: 05-作用域插槽.html 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/7/5 13:15 8 @version: html5 9 --> 10 11 <!DOCTYPE html> 12 <html lang="en"> 13 <head> 14 <meta charset="UTF-8"> 15 <title>05-作用域插槽</title> 16 </head> 17 <body> 18 <div id="app"> 19 <h2>{{ message }}</h2> 20 <cpn1> 21 <template slot-scope="slot"> 22 <span>{{slot.cdata.join('****')}}</span> 23 </template> 24 </cpn1> 25 <cpn1></cpn1> 26 <cpn1> 27 <template slot-scope="slot"> 28 <span>{{slot.cdata.join('^^^^')}}</span> 29 </template> 30 </cpn1> 31 </div> 32 33 <template id="cpn1"> 34 <div> 35 <h2>我是子组件1</h2> 36 <slot :cdata="carList"> 37 <ul> 38 <li v-for="item in carList">{{item}}</li> 39 </ul> 40 </slot> 41 </div> 42 </template> 43 <script src="../js/vue.js"></script> 44 <script> 45 const cpn1 = { 46 template: '#cpn1', 47 data(){ 48 return{ 49 carList:['AE86','GR86','WRX','WRX STI','丰田86'] 50 } 51 } 52 } 53 54 const app = new Vue({ 55 el: '#app', 56 data: { 57 message: 'hello' 58 }, 59 components: { 60 cpn1 61 } 62 }) 63 </script> 64 </body> 65 </html>
页面如下:
核心代码解析:
1.在子组件模板中给插槽一个绑定属性,名字任意取,绑定子组件中的data,carList
,
2.在父组件模板的子组件使用内部定义template标签,这里需要给template一个属性,slot-scope,vue2.5.x以后可以省略,此处为了兼容vue 2.5.x以下的代码。
3.在模板内部通过slot.cdata调用子组件内的数据
本文来自博客园,作者:kaer_invoker,转载请注明原文链接:https://www.cnblogs.com/invoker2021/p/14971991.html