一、插槽 slot
为什么使用 slot
slot 翻译为插槽,插槽的目的是让我们原来的设备具备更多的扩展性;
组件的插槽,也是为了让我们封装的组件更加具有扩展性,让使用者可以决定组件内部的一些内容到底展示什么;
1、slot插槽的基本使用
在子组件中,使用特殊的元素 <slot>
就可以为子组件开启一个插槽,该插槽插入什么内容取决于父组件如何使用;
<body> <div id="app"> <!--使用默认值--> <cpn></cpn> <!--替换默认值--> <cpn><p>p标签</p></cpn> <!--多个值--> <cpn> <div> <h4>Vue</h4> <p>slot插槽</p> </div> </cpn> </div> <template id="cpn"> <div> <h3>组件标题</h3> <p>组件内容</p> <!--插槽, button是插槽中的默认值--> <slot><button>按钮</button></slot> </div> </template> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { }, components: { cpn: { template: '#cpn' } } }) </script> </body>
2、具名插槽
当子组件的功能复杂时,子组件的插槽可能并非是一个,比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边,
那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?这个时候,我们就需要给插槽起一个名字,这就是具名插槽;
具名插槽的使用很简单,只要给 slot 元素一个 name 属性即可:<slot name='myslot'></slot>
<body> <div id="app"> <!--默认--> <cpn></cpn> <!--替换后--> <cpn><span slot="left">标题</span></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: {}, components: { cpn: { template: '#cpn' } } }) </script> </body>
3、编译作用域
父组件模板的所有东西,都会在父级作用域内编译
子组件模板的所有东西,都会在子级作用域内编译
<body> <div id="app"> <!--这里isShow为true,模板里的内容可以显示--> <cpn v-show="isShow"></cpn> </div> <template id="cpn"> <div> <h4>子组件</h4> <!--这里的isShow为false,按钮不会显示--> <button v-show="isShow">按钮</button> </div> </template> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { isShow: true }, components: { cpn: { template: '#cpn', data() { return { isShow: false } } } } }) </script> </body>
4、作用域插槽
作用域插槽是 slot 一个比较难理解的点,一句话总结就是:
父组件替换插槽的标签,但是内容由子组件来提供;
<body> <div id="app"> <!--默认显示--> <cpn></cpn> <!--要求:中间用‘-’连接显示,使用作用域插槽slot-scope,拿到子组件中的数据--> <cpn> <template slot-scope="slot"> <span>{{slot.data.join(' - ')}}</span> <!--这里的data就是下面模板里自定义的data--> </template> </cpn> </div> <template id="cpn"> <div> <slot :data="pLanguage"> <!--此处的'data'可以自己定义--> <ul> <li v-for="item in pLanguage">{{item}}</li> </ul> </slot> </div> </template> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: {}, components: { cpn: { template: '#cpn', data() { return { pLanguage: ['Java', 'Scala', 'Python', 'Go'] } } } } }) </script> </body>