017 vue的插槽的使用
[A] slot插槽
在开发中,我们经常遇到一个模块中大部分内容相同,部分内容不一样的情况,这个模块可以写成一个组件,
组件中相同的内容保留,不同的内容暴露在组件预留的插槽中,即可实现最优化代码。
[B] 组建中插槽的使用
1. 让我们封装额组件更具有拓展性
2. 让使用者可以决定组件内部的一些内容到底展示什么
[C] 插槽的基本使用方法
1. 在组件模板中预留插槽
示例代码:
<template> <div> 这是组件1 <input type="tetx"> <slot></slot> // 预留一个插槽 </div> </template>
【注】此外,slot插槽中也可以写默认值,当HTML页面中未在插槽中填写内容时,将显示默认内容
如: <slot><span>好啦</span></slot>
2. 在调用组件时,向插槽中加入自定义内容
如:
<div id="app"> <cpn><button>取消啦</button></cpn> // 这个按钮将替换原模板中的slot标签 <cpn></cpn> <cpn></cpn> </div>
[D] 具名插槽
在一个组件中,我们可以改变组件的多个地方,这里我们就需要在一个组件中加入多个插槽,
此时,我们需要给组件中的每个插槽设置一个name属性,以便于在html中在特定的那个插槽中填写内容,
这些有name属性的插槽,我们称之为具名插槽
具名插槽的使用方法:
1. 在组件模板中加入多个插槽,并给每个插槽设置不同的name属性
示例代码:
<template>
<div>
这是组件1
<input type="tetx">
<slot name = "left">左边</slot>
<slot name = "center">中间</slot>
<slot name = "right">右边</slot>
</div>
</template>
2. 在html页面中使用组件时,在添加的内容的外标签红加入slot属性,指定要添加到的那个插槽
示例代码:
<div id="app"> <cpn><span slot="center">修改后的</span></cpn> </div>
[E] 编译作用域
一个组件在使用时,会调用一些属性值,但是它只能调用自己的属性值,即作用域在本组件内。
编译作用域的官方准则:
父组件模板的所有东西都会在父级作用域内编译;
子组件模板的所有东西都会在子级作用域内编译;
案例1:
<body> // 1. html页面元素 <div id="app"> <cpn v-show="isshow"></cpn> // 这里调用了isshow属性 </div> // 全局组件cpn的组件模板 <template id="mycpn"> <div> 这是组件1 </div> </template> <script> // 2. 全局组件cpn Vue.component("cpn", { template: "#mycpn", data(){ return { isshow: false, d2: 20 } } }); // 3. vue实例 new Vue({ el: "#app", data:{ isshow: true, age:20 } }) </script> </body>
【分析】
1. 在本案例中,页面元素中调用了全局组件cpn,并使用了isshow这个属性
2. 但在本案例中,vue实例以及全局组件中军有isshow属性
3. 由于html页面中的元素写在#app中,也就是说在写在vue实例里面
4. 因此,该html中调用的属性值为vue实例中的isshow值
【笔者理解,不知是否正确】在定义组件中,vue实例才是一个根组件,全局组件为vue实例的最近子组件
[F] 作用域插槽
作用域插槽的作用是实现:父组件替换插槽的标签,但是内容由子组件来提供
步骤:
1. 在子组件的模板中设置插槽,并通过v-bind将需要传递的数据绑定在自定义的变量中,这个自定义的变量的值即为我们需要的子组件的数据
如:
<template id="mycpn">
<div>
这是子组件
<slot :data="languages"></slot>
</div>
</template>
2. 在html页面中调用vue实例中的子组件时,标签内添加slot-scope="slot",
在内部通过slot.自定义的变量,即可访问子组件穿过案例的内容
实例:
<div id="app">
<cpn>
<div slot-scope="slot">
<span v-for="item in slot.data">{{item}}*</span>
</div>
</cpn>
</div>
【完整案例代码】
<body> // html页面元素 <div id="app"> <cpn> // 2.在页面中引用vue实例的子组件,在插槽中插入的内容中加入行内属性slot-scope="slot" // 此后,在内部可以通过slot.data中访问子组件的languages的数据了 <div slot-scope="slot"> <span v-for="item in slot.data">{{item}}*</span> </div> </cpn> </div> // 子组件的模板内容 <template id="mycpn"> <div> 这是子组件 <slot :data="languages"></slot> // 1. 在子组件模板定义的插槽中将languages数据传过来,保存在data中 </div> </template> <script> // vue实例 new Vue({ el: "#app", data:{ isshow: true, age:20 }, components:{ cpn: { template:"#mycpn", data(){ return { languages:["C++", "Python", "Go", "JavaScript", "JAVA", "C#"] } }, }, } }) </script> </body>