vue实用组件——表格

  之前用了一下vue-bootstrap,感觉里面的表格组件特别好用,但是如果仅仅为了使用表格就引入bootstrap,似乎有点不划算。所以自己就试着实现了一下bootstrap里面表格的部分功能,目前只是实现了表格内容的排版和列排序功能。后面再慢慢实现更多的功能吧,比如详情框等等。

  另外说一点点个人对bootstrap的使用感受吧,它的便捷是有目共睹的,能快速搭建好项目UI,排版也很优雅好看,但是不太适用于已定好UI设计稿的项目,因为它的布局是很灵活的,在排版上,尺寸大致能遵循设计稿,但是不能较真,如果非要和设计稿保持一致,排版尺寸还原精确到1个像素的话,bootstrap的便捷性就要大打折扣了,因为会有大量的样式需要覆盖。

效果如下:

父组件需传递的数据格式如下:

      

代码如下:

<template>
<div class="d-table">
<ul class="listheader">
<li v-for="(it, key) in fields" :key="key">
<span
:class="{'up': sortField === key && sortrole > 0,'down': sortField === key && sortrole < 0}"
v-if="it.sort"
class='sort'
@click.capture="switchSort(key)"
><slot :name="key + '_H'" :data="{field: it, colum: key}">{{ $t(it.label) | cap }}</slot></span>
<span v-else><slot :name="key + '_H'" :data="{field: it, colum: key}">{{ $t(it.label) | cap }}</slot></span>
</li>
</ul>
<div class="listbody">
<div v-for="(it, i) in list" @click="rowClick(i, it)" :key="i">
<ul>
<li v-for="n in keys.length" :key="n">
<slot :name="keys[n-1]" :data="unitedata(i, it, n)">{{ it[keys[n-1]] }}</slot>
</li>
</ul>
</div>
</div>
</div>
</template>

<script>

export default {
props: {
items: {
type: Array,
default: () => ([])
},
fields: {
type: Object,
default: () => ({})
},
sortBy: {
type: String,
default: ''
}
},
data () {
return {
sortrole: 1,
sortField: this.sortBy,
detailshowIndex: -1
}
},
computed: {
keys () {
return Object.keys(this.fields)
},
list () {
const arr = this.items
if (this.sortField) {
const str = String(this.items[0][this.sortField]).charAt(0)
if (isNaN(str) && str !== '-' && str !== '+') {
arr.sort((x, y) => { // 当x[this.sortField]为对象时,未做判断处理
return this.sortrole * x[this.sortField].localeCompare(y[this.sortField])
})
} else {
arr.sort((x, y) => {
return this.sortrole * (x[this.sortField] - y[this.sortField])
})
}
}
const len = arr.length
for (let i = 0; i < len; i++) {
arr[i].detailShowing = false
}
return arr
}
},
mounted () {
},
methods: {
rowClick (i, it) {
this.$emit('rowClick', i, it)
},
unitedata (index, item, n) { // params: 当前行数,当前行的数据包(Object), 当前行的列数
let obj = { index, item }
obj.field = this.fields[this.keys[n - 1]]
obj.value = item[this.keys[n - 1]]
return obj
},
switchSort (key) {
let ele = event.target
while (ele.parentNode.tagName !== 'LI') {
ele = ele.parentNode
}
if (ele.classList.value.indexOf('up') > -1) {
this.sortrole = -1
} else {
this.sortrole = 1
}
this.sortField = key
}
}
}
</script>

<style scoped lang="scss">
.d-table {
background-color: #fff;
padding: 10px 0;
.listheader {
border-bottom: 1px solid #b7b7b7;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
padding: 0 10px;
&>li {
font-weight: bold;
16.5%;
overflow: hidden;
padding: 10px 0;
span.sort {
cursor: pointer;
position: relative;
&:before, &:after {
position: absolute;
right: -16px;
content: '';
display: inline-block;
border-right: 6px solid transparent;
border-left: 6px solid transparent;
}
&:before {
border-top: 6px solid #ababab;
top: 12px;
}
&:after {
border-bottom: 6px solid #ababab;
top: 5px;
}
&.down {
&:before {
border-top: 6px solid #21a185;
}
}
&.up {
&:after {
border-bottom: 6px solid #21a185;
}
}
}
}
}
.listbody {
&>div {
&:hover {
background-color: #f0f0f0;
}
&:first-child {
margin-top: 0;
}
ul {
padding: 0 10px;
display: flex;
justify-content: space-between;
li {
16.5%;
overflow: hidden;
padding: 10px 0;
}
}
}
}
}
</style>

可能存在谬误,欢迎指正,不胜感激!
本人前端水平有限,写的知识点可能有谬误,欢迎留言指正,如果看到,我将第一时间回复。感谢支持!
原文地址:https://www.cnblogs.com/qddyh/p/10386324.html