💕效果
样式虽然非常丑,但是不要太在意,咱们是来学习Vue写组件的,样式这东西右手就行。。。
💕需求
🐱🏍行,看完需求,那咱就开始!
😜组件结构
大致是有三部分组成
- Ktable.vue 就是table
- Ktablecoloumn.vue 来存储表格标题
- Kline.vue 来生成每一行数据
最后再来一个 index.vue 当我们的测试用例
👏目录结构
😆index.vue
<template>
<!-- 把tableData,表格数据传入table组件, -->
<k-table :model="tableData" :prop="label">
<!--
sortable:是否排序,点击标题内的button触发
table-cluomn:KtableColumn组件传来的生成的列的顺序
prop:每个格子的属性名
label:每个格子的中文标题
-->
<k-table-column
:sortable="true"
@table-cluomn="cluomn($event)"
:prop="'big'"
:label="'大小'"
></k-table-column>
<k-table-column
:sortable="true"
@table-cluomn="cluomn($event)"
:prop="'address'"
:label="'地址'"
></k-table-column>
<k-table-column
:sortable="true"
@table-cluomn="cluomn($event)"
:prop="'name'"
:label="'姓名'"
></k-table-column>
<k-table-column
:sortable="true"
@table-cluomn="cluomn($event)"
:prop="'date'"
:label="'日期'"
></k-table-column>
</k-table>
</template>
<script>
// 导入组件
import KTable from "./Ktable.vue";
// import KTableColumn from "./KtableColumn.vue";
import KTableColumn from "@/components/Ktable/KtableColumn.vue";
// import KTableColumn from "comps/Ktable/KtableColumn.vue";
export default {
components: { KTable, KTableColumn },
data() {
return {
// 动态获取表格 标题的顺序 big,address,name,date
label: [],
// 表格数据
tableData: [
{
big: 10,
date: "2016-05-02",
name: "1王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
big: 0,
date: "2016-05-04",
name: "2王小虎",
address: "上海市普陀区金沙江路 1517 弄",
},
{
big: 1,
date: "2016-05-01",
name: "4王小虎",
address: "上海市普陀区金沙江路 1519 弄",
},
{
big: 3,
date: "2016-05-03",
name: "3王小虎",
address: "上海市普陀区金沙江路 1516 弄",
},
],
};
},
mounted() {},
methods: {
// 通过KtableColumn组件的this.$emit() 把每一个列的标题传过来,不然生成列的顺序会是data 里面tableData的顺序
cluomn(e) {
// 每次生成一个列的标题就push一个标题到label
this.label.push(e);
},
},
};
</script>
<style>
</style>
👌kTable.vue
<template>
<table border="1">
<tr>
<!-- 标题行插槽 用来接收 KtableColumn组件 -->
<slot></slot>
</tr>
<!-- 每一行的组件,根据index过来的数组生成行内数据 -->
<!--
model:传入每一个数组元素
prop:标题的顺序,用来传给下一级组件,来实现标题和列的对应
-->
<k-line v-for="(item, index) in model" :model="item" :prop="prop" :key="index"></k-line>
</table>
</template>
·
<script>
import KLine from "./Kline.vue";
export default {
components: { KLine },
props: {
// 绑定的tabledata
model: {
type: Array,
},
// 标题顺序
prop: {
type: Array,
},
},
mounted() {
},
methods: {},
};
</script>
<style>
</style>
💋KtableColumn.vue
<template>
<th>
<!-- 展示列名 -->
<span>{{ label }}</span>
<!-- button 实现升降排序 -->
<button @click="sort('asc')" v-if="sortable">升序</button>
<button @click="sort('desc')" v-if="sortable">降序</button>
</th>
</template>
<script>
export default {
props: {
// 当前行的标签属性名
prop: {
type: String,
default: "",
},
// 当前行的标签属性文本
label: {
type: String,
default: "",
},
// 是否排序
sortable: {
type: Boolean,
default: true,
},
},
data() {
return {
// 实现排序功能
"asc-n": (a, b) => a - b,
"desc-n": (a, b) => b - a,
"asc-s": (a, b) => a.localeCompare(b),
"desc-s": (a, b) => b.localeCompare(a),
};
},
mounted() {
// 传回父组件,通知父组件把字符串加入顺序数组
this.$emit("table-cluomn", this.prop);
},
methods: {
sort(type) {
// 是否排序
if (this.sortable) {
// 对父父亲元素进行排序
this.$parent.$parent.tableData.sort((a, b) => {
// 调用排序规则,传入排序方式asc、desc,然后判断数据类型进行拼接后调用方法实现排序
return this[type + this.getSortType(a[this.prop])](
a[this.prop],
b[this.prop]
);
});
}
},
// 处理排序类型
getSortType(val) {
// 返回标识串进行拼接
return typeof val === "string" ? "-s" : "-n";
},
},
};
</script>
<style>
</style>
😁Kline.vue
<template>
<tr>
<!--
生成一行数据,
遍历生成的标题顺序,
从每一个对象中取出用户选定的标题的数据
-->
<td v-for="td in prop" :key="td">{{ model[td] }}</td>
</tr>
</template>
<script>
export default {
props: {
// 绑定的tabledata
model: {
type: Object,
},
// 标题顺序
prop: {
type: Array,
},
},
data() {
return {
};
},
mounted() {
},
};
</script>
<style>
</style>