简介
一个不怎么高度自定义的挪动端table
组件,可创立不定数量的列的table
(本人写着玩为了当前保护批改款式不便封装起来的
实现思路
- 表格头部一个循环:循环渲染每一列的列名
- 表格内容两重循环:外层循环渲染行,内层循环渲染每一行的每一列的内容
实现
环境:vue
+ vantui
,用van-row
+ van-col
模仿行和列
// 封装的table组件<template> <div class="fake-table"> <van-row class="fake-table__head"> <van-col class="col" v-for="(item, index) in headData" :key="index" :span="item.span">{{item.name}}</van-col> </van-row> <van-row class="fake-table__body" v-for="(item, index) in bodyData" :key="index"> <template v-for="(colItem, colIndex) in headData"> <van-col class="col" :span="colItem.span" :key="colIndex" v-if="colItem.prop"> <-- 这里其实重点只有关注v-model绑定的属性名。其余属性看我的项目具体须要,比如说placeholder也能够绑定:placeholder="item.placeholder"等等,只有传进来的数组合乎数据结构就行 --> <van-field v-model="item[colItem.prop]" placeholder="请输出名称" :disabled="item.editDisable" :class="[item.editDisable ? 'input-diabled': 'input-abled']"/> </van-col> <-- 这里是我的项目须要,不让事件冒泡,如果不须要能够去掉.stop修饰符。而capture就是用来捕捉slot进来的元素的事件的,因为在父组件定义事件的话无奈取到这里循环的colIndex --> <van-col class="col" :span="colItem.span" :key="colIndex" @click.stop.capture="doThis($event, index)" v-else> <slot></slot> </van-col> </template> </van-row> </div></template><script>export default { props: { headData: { type: Array, default: () => [] }, bodyData: { type: Array, default: () => [] } }, methods: { doThis(e, rowIdx) { if(e.target.id === 'edit') { this.$emit('edit', rowIdx) } else if(e.target.id === 'delete') { this.$emit('delete', rowIdx) } } }}</script><style lang="less" scoped>@inputPaddingLeft: 5px;@colPaddingLeft: 10px;.fake-table /deep/ .van-field__control { padding-left: @inputPaddingLeft;}.col /deep/ .van-cell { padding: 0;}.col /deep/ .input-diabled { border: none;}.col /deep/ .input-abled { border: 1px solid #DDDDDD;}.table-col { height: 100%; display: flex; justify-content: flex-start; align-items: flex-start; font-family: PingFangSC-Medium, PingFang SC; color: #313131;}.fake-table { margin: 0 12px; &__head, &__body { border: 1px solid #DDDDDD; &:not(:last-child) { border-bottom: none; } } &__head { height: 40px; background: #F5FAFF; .col:extend(.table-col) { font-size: 14px; font-weight: 500; line-height: 20px; padding: @colPaddingLeft; } } &__body { .col:extend(.table-col) { font-size: 13px; font-weight: 400; line-height: 18px; padding: @colPaddingLeft @colPaddingLeft @colPaddingLeft calc(@colPaddingLeft - @inputPaddingLeft); &:last-child { padding-left: @inputPaddingLeft; } } }}</style>
应用
// 父组件// html<fake-table :headData="tableHead" :bodyData="matirialUsed" @edit="editMatirial" @delete="deleteMatirial"> <template> <van-icon id="edit" class="edit-btn" name="edit" size="14" color="#268AED" /> <van-icon id="delete" class="delete-btn" name="delete" size="14" color="#268AED" /> </template> </fake-table>// scriptimport fakeTable from '../../components/fake-table'// ...省略一些代码data { return { tableHead: [{ name: '资料名称', // 留神传进去的列名 span: '8', prop: 'name' // 留神传进去的列属性名,要跟理论获得的数据的属性名统一,如matirialUsed数组的每一项的属性名 }, { name: '型号', span: '6', prop: 'model' }, { name: '数量', span: '5', prop: 'num' }, { name: '操作', span: '5', prop: '' }], matirialUsed: [{ name: '', model: '', num: '0', editDisable: true, // 是否可编辑 }, { name: '', model: '', num: '0', editDisable: true, }, { name: '', model: '', num: '0', editDisable: true, }, { name: '', model: '', num: '0', editDisable: true, }] }}, components: { fakeTable }, methods: { editMatirial(idx) { let flag = this.matirialUsed[idx]['editDisable'] this.$set(this.matirialUsed[idx], 'editDisable', !flag) }, deleteMatirial(idx) { let temp = this.matirialUsed temp.splice(idx, 1) this.matirialUsed = temp }, }