一、自定义组件中多个 slot
很久之前就想把表格封装了,奈何那时太过担心自己的技术。今天趁着劲头大致看了一下,把表格封装了,倒是比想象中的要简单很多 O(∩_∩)O 哈哈~
暂且不考虑细节,大致封装表格要考虑的有:是否需要操作按钮、是否要对表格中的某些字段值进行修改或操作。这些就要用到多个 slot,我们要做的就是区分这些 slot,在对应的 slot 下写逻辑。
只有一个 slot 时,我们只需要在组件中想要改写的位置插入 <slot></slot> 标签就可以了。当有多个时,我们要在 slot 标签中写入 name 属性对 slot 进行区分。例如:
子组件:
<div><slot name="a"><slot><h2>标题</h2><p>段落文字文字文字文字</p><slot name="b"><slot>
</div>
父组件使用:
<my-text><h1 slot="a">我是大标题</h1> <!-- 父组件中的slot值对应子组件中name的值 --><span slot="b">20121-7-16</span>
</my-text><script>import myText from "组件所在路径";export default {components: { myText }}
</script>
二、slot 传参(利用 slot 子组件给父组件传参)
1. 插槽传值::自定义属性=值
如果要封装表格,有很多表格中都是会有一些操作,例如删除某一条数据、修改某条数据,父组件都要从子组件中拿到对应的 id 或者那一列的数据。这里我们只要在子组件的 slot 插槽中绑定一个自定义属性,再把值传给这个属性就好了,例如:
模板中使用:
子组件:
<el-table-column v-if="operateShow" label="操作" align="center" :min-width="operateWidth" fixed="right"><template slot-scope="scope"><!-- 自定义data属性,把值传给data属性。这个data是自己随便定义的一个名称 --><slot name="operate" :data="scope.row"></slot></template>
</el-table-column>
父组件:
<!-- 父组件接收参数时:slot-scope="自定义名称" -->
<template slot="operate" slot-scope="myProps"><!-- 调用数据:父组件slot-scope的自定义名称.子组件slot标签中自定义数据名称.需要且有效的字段名 --><el-button type="warning" size="mini" icon="el-icon-edit-outline" @click="update(myProps.data.url)">下载</el-button>
</template>
循环中使用:
子组件:
<!-- 与在模板中直接使用的方法相同,:data传的是表格中每一行的所有数据,:index传的是所在行的索引 -->
<template v-for="(info, infoIndex) in tableInfo"><el-table-column :key="infoIndex" :prop="info.key" :label="info.value" align="center" :min-width="info.minWidth" show-overflow-tooltip ><!-- 给插槽命名、传值、序列号 --><slot :name="info.key" :data="info" :index="infoIndex"></slot></el-table-column>
</template>
父组件:
<!-- slot="所在列的某一个字段",并将这一列的字段值做处理 -->
<template slot="downloadDate" ><span>112</span>
</template>
2. 通过事件给父组件传值
这是自定义组件中最常用的一种方法。
子组件:通过 this.$emit() 的方式将值传递给父组件。
<template><div class="app"><input @click="sendMsg" type="button" value="给父组件传递值"></div>
</template>
<script>
export default {data () {return {//将msg传递给父组件msg: "我是子组件的msg",}},methods:{sendMsg(){//func: 是父组件指定的传数据绑定的函数,this.msg:子组件给父组件传递的数据this.$emit('func',this.msg)}}
}
</script>
父组件:
<template><div class="app"><child @func="getMsgFormSon"></child></div>
</template>
<script>
import child from './child.vue'
export default {data () {return {msgFormSon: "this is msg"}},components:{child,},methods:{getMsgFormSon(data){this.msgFormSon = dataconsole.log(this.msgFormSon)}}
}
三、v2.6.0关于slot的新写法
插槽 — Vue.js
在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即
v-slot
指令)。它取代了slot
和slot-scope
这两个目前已被废弃但未被移除且仍在文档中的 attribute。