封装的组件
<!-- 首页 -->
<template>
<div class="pager">
//如果tableConfig.title存在,这个div显示
<div class="table-title" v-if="tableConfig.title">
//如果tableConfig.title.btns存在,显示当前的template
<template v-if="tableConfig.title.btns">
//如果tableConfig.title.btns的长度>0,显示当前的template
<template v-if="tableConfig.title.btns.length > 0">
<el-button
:type="item.type"
//v-for循环遍历按钮
v-for="(item, index) in tableConfig.title.btns"
:key="index"
size="mini"
:icon="item.icon"
@click="fire(item.click)"
>{{ item.text }}</el-button
>
</template>
//否则,显示下面这个template
<template v-else>
<el-button
//type 类型 string primary / success / warning / danger / info / text
:type="tableConfig.title.btns.type"
//size 尺寸 string medium / small / mini
size="mini"
//icon 图标类名 string
:icon="tableConfig.title.btns.icon"
//点击事件
@click="fire(tableConfig.title.btns.click)"
>{{ tableConfig.title.btns.text }}</el-button
>
</template>
</template>
</div>
<el-table
ref="multipleTable" //相当于el-table的别名
:data="tableData" //data 显示的数据 array
max-height="450" //Table 的最大高度
@selection-change="checkChange" //Table Events-->当选择项发生变化时会触发该事件
style="width: 100%"
>
//表格的索引列
<el-table-column
type="selection" //多选
align="center" //对齐方式-->居中对齐
header-align="center" //表头对齐方式,若不设置该项,则使用表格的对齐方式
width="60"
v-if="tableConfig.boxType == 'checkbox'"
/>
<template v-for="(column, index) in tableConfig.columns"> //渲染table表头所有列
<el-table-column
label="选择"
align="center"
header-align="center"
width="60"
:key="radioKey(tableConfig.key, index)"
v-if="tableConfig.boxType == 'radiobox' && index === 0"
>
<template slot-scope="scope">
<el-radio
v-model="radioValue"
:label="scope.row[tableConfig.key]"
@change="radioChange(scope.row)"
> </el-radio
>
</template>
</el-table-column>
//操作列
<el-table-column
:label="column.label"
:header-align="column.align"
:align="column.align"
:width="column.width"
fixed="right" //列是否固定在左侧或者右侧,true 表示固定在左侧
v-if="column.prop == 'operate'"
:key="tableConfig.key + index"
>
<template slot-scope="scope">
<template v-for="(btn, idx) in column.items">
<el-button
@click="fire(btn.click, scope.row)"
type="text"
size="small"
v-if="isCondition(btn, scope.row)"
:key="idx"
>{{ btn.text }}</el-button
>
</template>
</template>
</el-table-column>
<el-table-column
:prop="column.prop"
:label="column.label"
:header-align="column.align"
:align="column.align"
:width="column.width"
:key="tableConfig.key + index"
v-else-if="column.type === 'switch'"
>
<template slot-scope="scope">
<el-switch //Switch 开关
v-model="scope.row[column.prop]"
:active-value="'1'"
:inactive-value="'0'"
:disabled="column.disabled"
@change="fire(column.change, scope.row)"
></el-switch>
</template>
</el-table-column>
//渲染列
<el-table-column
:prop="column.prop"
:label="column.label"
:header-align="column.align"
:align="column.align"
:width="column.width"
:key="tableConfig.key + index"
v-else-if="column.render"
>
<template slot-scope="scope">
<div v-html="renderHTML(column.render, scope.row)"></div>
</template>
</el-table-column>
<el-table-column
:prop="column.prop"
:label="column.label"
:header-align="column.align"
:align="column.align"
:width="column.width"
:key="tableConfig.key + index"
v-else
>
</el-table-column>
</template>
</el-table>
//分页
<div class="pagination">
<template v-if="isChecked == true">
<el-checkbox
:indeterminate="indeterminate"
v-model="checkAll"
@change="checkAllChange"
>已选择({{ selectList.length }})</el-checkbox
>
</template>
//分页中的删除按钮
<template v-if="tableConfig.btns">
// 判断按钮有多个?
<template v-if="tableConfig.btns.length > 0">
<el-button
:type="item.type"
v-for="(item, index) in tableConfig.btns"
:key="index"
size="mini"
:icon="item.icon"
@click="fire(item.click)"
>{{ item.text }}</el-button
>
</template>
//按钮有一个
<template v-else>
<el-button
:type="tableConfig.btns.type"
size="mini"
:icon="tableConfig.btns.icon"
@click="fire(tableConfig.btns.click)"
>{{ tableConfig.btns.text }}</el-button
>
</template>
</template>
<el-pagination
background
layout="total, prev, pager, next,sizes, jumper"
:total="total" //总条目数
:page-sizes="pageSizes" //每页显示个数选择器的选项设置 Number[]
:page-size="pageSize" //每页显示条目个数 Number
@size-change="sizeChange" //pageSize 改变时会触发-->每页条数size
@current-change="currentChange" //currentPage 改变时会触发-->当前页currentPage
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
props: ['tableConfig'],
computed: {
renderHTML: function () {
return function (render, item) {
return render(item)
}
},
isChecked: function () {
return this.tableConfig.checked == null || this.tableConfig.checked == true
},
radioKey: function () {
return function (key, index) {
return key + 'radio' + index
}
},
isCondition: function () {
return function (column, item) {
return column && column.condition ? column.condition(item) : true
}
},
},
data() {
return {
total: 0,
pageNumber: 1,
pageSize: 20,
pageSizes: [10, 20, 50, 100],
params: {},
tableData: [],
selectList: [],
indeterminate: false,
checkAll: false,
radioValue: null,
}
},
created() {
if (!this.tableConfig.key) {
console.warn('please set the key in the tableConfig!')
}
this.query()
},
methods: {
fire(eventName, item) {
this.$emit(eventName, item) //子传父
},
setParams(params) {
this.params = params || {}
},
getSelectList() {
return this.selectList
},
getParams() {
return Object.assign(
this.tableConfig.params || {},
{
//start和limit是项目特定的参数名
start: (this.pageNumber - 1) * this.pageSize, //page
limit: this.pageSize, //size
},
this.params
)
},
//获取表格数据
query() {
this.tableConfig.request(this.getParams()).then((result) => {
if (result.returnCode === '0') {
this.total = result.bean.total
this.tableData = result.beans || []
}
})
},
checkChange(val) {
this.selectList = val
this.refreshStatus()
},
refreshStatus() {
this.indeterminate =
this.selectList.length > 0 && this.selectList.length < this.tableData.length
? true
: false
this.checkAll = this.selectList.length === this.tableData.length ? true : false
},
checkAllChange(value) {
if (value) {
this.selectList = this.tableData
for (let i = 0; i < this.tableData.length; i++) {
this.$refs.multipleTable.toggleRowSelection(this.tableData[i])
}
} else {
this.$refs.multipleTable.clearSelection()
this.selectList = []
}
},
sizeChange(pageSize) {
this.pageNumber = 1
this.pageSize = pageSize
this.query()
},
currentChange(pageNumber) {
this.pageNumber = pageNumber
this.query()
},
radioChange(row) {
this.selectList = [row]
this.$emit('radioChange', this.selectList[0])
},
setRadioValue(val) {
this.radioValue = val
},
},
}
</script>
<style scope>
.table-title {
height: 40px;
text-align: right;
}
.table-title .el-button {
margin-top: 5px;
margin-right: 20px;
}
.el-pagination {
float: right;
margin-top: 6px;
margin-bottom: 6px;
margin-right: 20px;
}
.pager /deep/ .el-pagination__jump {
margin-left: 12px;
}
.pager /deep/ .el-table--border::after,
.pager /deep/ .el-table--group::after,
.pager /deep/ .el-table::before {
background-color: transparent;
}
.pager /deep/ .el-table--border,
.pager /deep/ .el-table--group {
border-left: none;
}
.pager /deep/ .el-table-column--selection .cell {
padding-left: 0 !important;
padding-right: 0 !important;
}
.pagination {
height: 44px;
line-height:44px;
}
.pagination /deep/ .el-checkbox {
margin: 12px 14px 12px 23px;
}
.pager /deep/ .el-table--border th.el-table__cell,
.pager /deep/ .el-table__fixed-right-patch {
background-color: #f9f9f9;
}
.pager /deep/ .el-checkbox__label{
font-size: 12px;
}
</style>
table 表格实现多选:
手动添加一个el-table-column,设type属性为selection
点击事件写成 fire() ???
// 子组件给父组件传数据:
// 父组件提 前给子组件一个函数,子组件调用函数,父组件收到参数
- 将表格封装成子组件,点击按钮时,会调用父组件pager.vue中的click事件@click=“fire(item.click)”,item是tableConfig.title.btns的某一个按钮对象,fire(item.click)相当于子知道了父组件想点击哪个事件按钮
- 了解了需求之后子组件去方法里找fire(),fire(eventName, item) { this.KaTeX parse error: Expected 'EOF', got '}' at position 25: …tName, item) }̲,通过this.emit()把item传给父。
- 想点击删除按钮,肯定在index.vue里得写delete()事件叭,根据啥删除?删除啥?你要获取到子组件中用户点得是哪行数据叭,这个就是我想传过来得item
表格中的各列
checkbox组件中的indeterminate 状态
indeterminate | checkAll | el-checkbox(已选择) |
---|---|---|
true | false | 曰 |
false | true | ☑ |
false | false | 口 |
@selection-change=“checkChange”
Table Events–>当选择项发生变化时会触发该事件
样式
vue组件中,在style设置为scoped的时候,里面在写样式对子组件是不生效的,如果想让某些样式对所有子组件都生效,可以使用 /deep/ 深度选择器。
效果图
该组件要引入封装的组件
<template>
<div class="container">
<div class="title">网元类型管理</div>
<el-form class="el-row query-form" ref="form" :model="form" label-width="150px">
<el-form-item class="el-col el-col-6" label="网元类型名称" prop="netElementName">
<el-input placeholder="请输入网元类型名称" v-model="form.netElementName" />
</el-form-item>
<el-form-item class="el-col el-col-6" label="网元类型标识" prop="netElementCode">
<el-input placeholder="请输入网元类型标识" v-model="form.netElementCode" />
</el-form-item>
<el-button type="primary" size="small" @click="search">查询</el-button>
<el-button size="small" @click="resetForm">重置</el-button>
</el-form>
<pager
ref="pager" //可以理解为<pager/>组件的别名
:tableConfig="tableConfig"
//@是v-on的缩写,通过父组件给子组件绑定一个自定义事件实现:子给父传递数据
@add="add"
@edit="edit"
@delete="batchDelete"
></pager>
<EditNode ref="dialog" :callback="search"></EditNode>
</div>
</template>
<script>
import pager from '@/components/pager/pager'
import { getList, batchDelete } from '@/api/modules/node'
import EditNode from './EditNode.vue'
export default {
components: {
pager,
EditNode,
},
data() {
return {
form: {
netElementName: undefined,
netElementCode: undefined,
},
tableConfig: { //是一个对象-->表格配置
boxType: 'checkbox', //表格索引列的type
key: 'netElementId',
request: getList, //请求方法
title: {
//新增按钮
btns: {
type: 'primary',
icon: 'el-icon-plus',
text: '新增',
click: 'add',
},
},
//表头配置项
columns: [
{
prop: 'netElementName',
label: '网元类型名称',
width: 120,
},
{
prop: 'icon',
label: '图标(正常、告警、异常)',
width: 250,
align: 'center',
key: 'filePath',
render: (item) => {
return `<img src="${item.netElementIconNormal}"><img src="${item.netElementIconAlarm}"><img src="${item.netElementIconAbnormal}">`
},
},
{
prop: 'netElementCode',
label: '网元类型标识',
width: 240,
},
{
prop: 'orderNum',
label: '排序号',
width: 60,
align: 'center',
},
{
prop: 'netElementRemark',
label: '描述',
},
{
prop: 'operate',
width: 100,
label: '操作',
align: 'center',
items: [
{
text: '编辑',
click: 'edit',
},
],
},
],
//删除按钮
btns: {
type: 'primary',
text: '删除',
click: 'delete',
},
},
}
},
methods: {
search() {
this.$refs.pager.setParams(this.form)
this.$refs.pager.query()
},
resetForm() {
this.$refs.form.resetFields()
this.$refs.pager.setParams(this.form)
this.$refs.pager.query()
},
batchDelete() {
let selectList = this.$refs.pager.getSelectList()
if (!selectList || selectList.length === 0) {
this.$message.error('请选中网元类型后进行删除')
return
}
var nameStr = Array.from(selectList, (item) => item.netElementName).join('、')
this.$confirm(`确定删除网元类型 [ ${nameStr} ] 吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
var ids = Array.from(selectList, (item) => item.netElementId)
batchDelete(ids).then((result) => {
if (result.returnCode === '0') {
this.$message.success('删除成功')
this.$refs.pager.query()
} else {
this.$message.error('删除失败')
}
})
})
.catch(() => {})
},
add() {
this.$refs.dialog.open()
},
edit(item) {
this.$refs.dialog.open(item)
},
},
}
</script>
<style>
.cell img {
width: 32px;
height: 32px;
margin: 0 5px;
/* padding-right: 10px; */
}
</style>
Layout布局
通过基础的 24 分栏,迅速简便地创建布局。
基础布局:通过 row 和 col 组件,并通过 col 组件的 span 属性我们就可以自由地组合布局。