前言
最近复习Vue时发现插槽真的很重要、很有用。以前竟然没怎重视😅。使用插槽,可以将重复性的代码进行整合,可以将样式进行统一。
打个比方:elementUI中的表格和分页条经常搭配在一起使用,分页条这部分代码其实一直在重复。我们可以将这部分进行封装,然后在插槽中写表格的部分(这部分的代码会写在后面)
复习时发现插槽这部分有slot
、slot-scope
、v-slot
这三个东西真的很懵逼,然后只能看官方文档和其他博客进行分析。
slot
slot实际上就是用于指定具名插槽的名
实例1、
//全局组件Test
Vue.component('test', {
template: `
<div>
<slot>默认信息</slot>
</div>
`
})
//使用,插槽内务内容
<test></test>
//插槽内有内容
<test>111<test>
当插槽内没有内容时会显示默认信息(当然你已经指定了默认内容),当插槽内有值时,插槽内的值会替换默认内容
现在还是没有用的slot,不是没用到而是对于默认的插槽,slot可以省略。上面的也可以写成下面的形式:
<test>
<div slot="default">111</div>
</test>
实例2、
当给插槽起一个别名时,slot是不能够再省略的。通过不同的名字,会将不同的内容放在不同的位置。
//全局组件Test
Vue.component('test', {
template: `
<div>
<slot name="footer"></slot>
<slot name="header"></slot>
<slot name="default"></slot>
</div>
`
})
//使用
<test>
<div slot="header">我是头</div>
<div slot="footer">我是尾</div>
<div slot="default">我是默认</div>
</test>
1、内容显示的位置取决于你定义的插槽的位置
2、对于未指定名称的内容,默认都是默认插槽(就是在默认插槽里显示)
slot-scope
上面的具名插槽只能显示内容,如果想要传递参数呢?那只能使用slot-scope
实例1、
<body>
<div id="app">
<test>
<div slot-scope="scope">
{{scope.info}}
</div>
</test>
</div>
</body>
<script type="text/javascript">
//全局组件Test
Vue.component('test', {
template: `
<div>
<slot :info="msg"></slot>
</div>
`,
data() {
return {
msg: "111"
}
}
})
new Vue({
el: '#app',
data: {
}
})
</script>
实例2、
如果即想要指定名称又想要传参呢?slot
和slot-scope
都需要使用
<body>
<div id="app">
<test>
<div slot="age" slot-scope="scope">{{scope.msg.name}}</div>
</test>
</div>
</body>
<script type="text/javascript">
//全局组件Test
Vue.component('test', {
template: `
<div>
<slot name="age" :msg="info"></slot>
</div>
`,
data() {
return {
info: {
age: 2,
name: 'ddsfd'
}
}
}
})
new Vue({
el: '#app',
})
</script>
v-slot
在 2.6.0 中,官方为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope,就是通过v-slot可以干slot和slot-scope两个的工作。
这里有个说明。使用v-slot后,v-slot不能再写在div上了,需要统一写在template中
实例1、只起slot的作用
<body>
<div id="app">
<test>
<template v-slot:name>
dddd
</template>
</test>
</div>
</body>
<script type="text/javascript">
//全局组件Test
Vue.component('test', {
template: `
<div>
<slot name="name"></slot>
</div>
`
})
new Vue({
el: '#app',
data: {
info: {
name: '111',
age: 5
}
}
})
</script>
注:
1、v-slot
只在2.6版本及以上可以生效,最初用了2.2版本,没效果还以为出错了呢。
2、v-slot
可以简写为#
,例如:
<test>
<template #name>
dddd
</template>
</test>
实例2、只起slot-scope的作用
<body>
<div id="app">
<test>
<template v-slot="scope">
{{scope.info}}
</template>
</test>
</div>
</body>
<script type="text/javascript">
//全局组件Test
Vue.component('test', {
template: `
<div>
<slot :info="msg"></slot>
</div>
`,
data() {
return {
msg: "你好"
}
}
})
new Vue({
el: '#app',
data: {
}
})
</script>
实例3:起两者的作用
<body>
<div id="app">
<test>
<template #msg="scope">
{{scope.info}}
</template>
</test>
</div>
</body>
<script type="text/javascript">
//全局组件Test
Vue.component('test', {
template: `
<div>
<slot name="msg" :info="msg"></slot>
</div>
`,
data() {
return {
msg: "你好"
}
}
})
new Vue({
el: '#app',
data: {
}
})
</script>
实例
实例以element UI为基础
封装分页查询
<template>
<div :style="tableStyle">
<!-- 页面标题 -->
<div class="item__title">{{ title }}</div>
<!-- table表格内容 -->
<slot name="table" :tableData="tableData"></slot>
<!-- 分页条 -->
<el-pagination :small="isSmall" background layout="prev, pager, next, sizes, total, jumper" :page-sizes="[20, 30, 50]" :page-size="tableData.pageSize"
:total="tableData.pageNumberAll" :current-page="tableData.pageNumber" @size-change="handleSizeChange" @current-change="page">
</el-pagination>
</div>
</template>
<script>
export default {
components: {},
props: {
title: {
type: String,
default: ''
},
url: {
type: String,
default: '',
required: true
},
params: {
type: Object,
default: () => {}
},
init: {
type: Boolean,
default: false,
required: true
},
tableStyle: {
type: Array,
default: () => {}
},
isSmall: {
type: Boolean,
default: false
}
},
data() {
// 这里存放数据
return {
// 表格数据
tableData: {
tableInfo: [],
loading: false,
pageSize: 20,
pageNumber: 1,
pageNumberAll: 0
}
};
},
watch: {
init(val) {
if(val) {
this.getTableInfo();
}
}
},
mounted() {
this.getTableInfo();
},
// 方法集合
methods: {
// 主表格分页点击事件
page(page) {
this.tableData.pageNumber = page;
this.getTableInfo(); // 更新
},
// 主表格调整每页显示条数
handleSizeChange(val) {
this.tableData.pageSize = val;
this.getTableInfo();
},
// 获取表格数据
getTableInfo() {
let querys = {
pageSize: this.tableData.pageSize,
pageNumber: this.tableData.pageNumber,
...this.params
};
this.tableData.loading = true;
this.$http.post(this.url,querys).then(({data: d}) => {
if(d.code == 0) {
this.tableData.loading = false;
this.tableData.tableInfo = d.data.records;
this.tableData.pageNumberAll = d.data.total;
}
});
}
}
};
</script>
<style lang="scss" scoped>
</style>
使用
<h-table title="售后核销分析" :init="true" :url="url" is-small :table-style="{height:'50%',width:'500px'}">
<template #table="scope">
<!-- {{ scope }} -->
<el-table ref="tableDemo" v-loading="scope.tableData.tabloading" :data="scope.tableData.tableInfo" style="width: 100%" height="calc(100% - 150px)" border :row-key="row => row.id">
<el-table-column type="selection" width="55" align="center" reserve-selection fixed></el-table-column>
<el-table-column type="index" width="55" label="序号" fixed align="center"></el-table-column>
<el-table-column label="创建日期" prop="gmtCreate" align="center" show-overflow-tooltip min-width="120">
<template v-slot:header>
<ever-table-header prop="gmtCreate" label="创建日期" type="date" @filtrate="filtrate"></ever-table-header>
</template>
</el-table-column>
</el-table>
</template>
</h-table>
<h-table title="售后核销分析" :init="true" :url="url" :table-style="{height:'50%'}">
<template #table="scope">
<!-- {{ scope }} -->
<el-table ref="tableDemo" v-loading="scope.tableData.tabloading" :data="scope.tableData.tableInfo" style="width: 100%" height="calc(100% - 150px)" border :row-key="row => row.id">
<el-table-column type="selection" width="55" align="center" reserve-selection fixed></el-table-column>
<el-table-column type="index" width="55" label="序号" fixed align="center"></el-table-column>
<el-table-column label="创建日期" prop="gmtCreate" align="center" show-overflow-tooltip min-width="120">
<template v-slot:header>
<ever-table-header prop="gmtCreate" label="创建日期" type="date" @filtrate="filtrate"></ever-table-header>
</template>
</el-table-column>
</el-table>
</template>
</h-table>
效果