您的位置:首页 > Web前端 > Vue.js

vue基于element-ui实现可编辑的简单表格

2020-05-19 17:03 253 查看

效果图


简单粗暴直接上代码,直接copy即可

表格组件代码:

<template>
<el-row>
<div @contextmenu.prevent="showMainMenu($event)">
<el-table :empty-text="emptyText" :fit="fit" :data="tableData" style="width: 100%" :max-height="maxHeight" border
@cell-click="mouseClick" highlight-current-row @row-contextmenu="rightClick" @cell-mouse-leave="mouseOut" ref="editTable">
<el-table-column type="index" width="50" label="序号" v-if="columnData.length!==0">
</el-table-column>
<el-table-column :prop="item.prop" :label="item.label" v-for="(item,index) in columnData" :key="index"
:min-width="item.width">
<template slot-scope="scope">
<template v-if="item.attributes.type=='input'">
<el-input @input="changeInput(item.prop,scope.row)" size="mini" v-show="scope.row['$edit$'+index]"
v-model="scope.row[item.prop]"></el-input>
<div class="table-span" :title="scope.row[item.prop]">
<span v-show="!scope.row['$edit$'+index]">{{scope.row[item.prop]}}</span>
</div>
</template>
<template v-else-if="item.attributes.type=='select'">
<div v-show="scope.row['$edit$'+index]">
<el-select size="mini" v-model="scope.row[item.prop]" @blur="scope.row['$edit$'+index]=true" @visible-change="selectVisible($event,item.prop,scope.row[item.prop],scope.row,item.attributes.selectData)"
@change="selectChange(item.prop,scope.row[item.prop],scope.row)">
<el-option :label="item.value" :value="item.key" v-for="(item,index) in item.attributes.selectData"
:key="index"></el-option>
</el-select>
</div>
<div v-show="!scope.row['$edit$'+index]">
<div class="table-span" :title="scope.row[item.prop]">
<span>{{renderer(item.prop,scope.row[item.prop])}}</span>
</div>
</div>
</template>
</template>
</el-table-column>
</el-table>
</div>
<e-vue-contextmenu ref="setting-dialog" class="brightness-setting-dialog">
<div class="br-operation" @click="addRow">
<div class="icon"><i class="el-icon-circle-plus-outline"></i></div>
<div class="text">新增一行</div>
</div>
<div class="br-operation" @click="inserRowBefore">
<div class="icon"><i class="el-icon-upload2"></i></div>
<div class="text">当前行前面插入</div>
</div>
<div class="br-operation" @click="inserRowAfter">
<div class="icon"><i class="el-icon-download"></i></div>
<div class="text">当前行后面插入</div>
</div>
<div class="br-operation" @click="upRow">
<div class="icon"><i class="el-icon-top"></i></div>
<div class="text">上移</div>
</div>
<div class="br-operation" @click="downRow">
<div class="icon"><i class="el-icon-bottom"></i></div>
<div class="text">下移</div>
</div>
<div class="br-operation" @click="deleteRow">
<div class="icon"><i class="el-icon-remove-outline"></i></div>
<div class="text">删除当前行</div>
</div>
<div class="br-operation" @click="deleteRows">
<div class="icon"><i class="el-icon-delete"></i></div>
<div class="text">删除所有行</div>
</div>
</e-vue-contextmenu>
</el-row>
</template>

<script>
export default {
data() {
return {}
},
props: {
//初始化空数据
initNum: {
type: Number,
required: false,
default: 0
},
//列头
columnData: {
type: Array,
required: true
},
//数据
tableData: {
type: Array,
required: true,
default: () => []
},
//最大高度
maxHeight: {
type: Number,
required: false
},
//不可被编辑字段
notIncluded: {
type: Array,
required: false,
default: () => []
},
//是否撑开
fit: {
type: Boolean,
default: false
},
//没有数据时提示
emptyText: {
type: String,
required: false,
default: () => "暂无数据"
}
},
computed: {},
methods: {
//点击单元格
mouseClick(row, column, cell, event) {
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
for (let i = 0; i < this.columnData.length; i++) {
if (this.columnData[i].prop === column.property)
row["$edit$" + i] = true;
else
row["$edit$" + i] = false;
}
},
//鼠标移出单元格
mouseOut(row, column, cell, event) {
for (let i = 0; i < this.columnData.length; i++) {
row["$edit$" + i] = false;
}
},
//监听输入框
changeInput(prop, row) {
this.$emit('changeInput', prop, row);
},
//监听下拉收起展开
selectVisible(event, prop, key, row, datas) {
if (!event) {
for (let i = 0; i < this.columnData.length; i++) {
row["$edit$" + i] = false;
}
}
this.$emit('selectVisible', event, prop, key, row);
},
//监听下拉框变化
selectChange(prop, key, row) {
this.$emit('selectChange', prop, key, row);
},
//表格右击
rightClick(row, column, event) {
this.rowIndex = row.$index$;
},
//菜单
showMainMenu(e) {
this.$refs['setting-dialog'].showMenu(e);
},
//new一个表格数据
getNewRow() {
let row = {};
this.$set(row, "$index$", this.tableData.length);
for (let i = 0; i < this.columnData.length; i++) {
this.$set(row, this.columnData[i].prop, "");
}
for (let i = 0; i < this.columnData.length; i++) {
if (this.notIncluded.length != 0) {
if (this.notIncluded.indexOf(this.columnData[i].prop) < 0) {
this.$set(row, "$edit$" + i, false);
}
} else {
this.$set(row, "$edit$" + i, false);
}
}
return row;
},
//索引重置(不然删除等操作会有错误)
reSort() {
for (let i = 0; i < this.tableData.length; i++) {
this.tableData[i].$index$ = i;
}
},
//新增一行
addRow() {
let row = this.getNewRow();
this.tableData.push(row);
if (this.$refs['setting-dialog'])
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
},
//向前插入
inserRowBefore() {
let row = this.getNewRow();
this.tableData.splice(this.rowIndex, 0, row);
this.reSort();
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
},
//向后插入
inserRowAfter() {
let row = this.getNewRow();
this.tableData.splice(this.rowIndex + 1, 0, row);
this.reSort();
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
},
//上移
upRow() {
if (this.rowIndex != 0) {
let row = this.tableData.splice(this.rowIndex, 1)[0];
this.tableData.splice(this.rowIndex - 1, 0, row);
this.reSort();
}
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
return;
},
//下移
downRow() {
if (this.rowIndex != this.tableData.length - 1) {
let row = this.tableData.splice(this.rowIndex, 1)[0];
this.tableData.splice(this.rowIndex + 1, 0, row);
this.reSort();
}
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
return;
},
//删除当前行
deleteRow() {
this.tableData.splice(this.rowIndex, 1);
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
this.reSort();
},
//删除所选行
deleteRows() {
this.tableData.splice(0);
if (this.$refs['setting-dialog'])
this.$refs['setting-dialog'].hideMenu();
},
//格式化(下拉框值进行key-value格式化)
renderer(prop, value) {
let me = this;
let renderer = null;
for (let i = 0; i < this.columnData.length; i++) {
if (this.columnData[i].prop === prop) {
let selectData = this.columnData[i].attributes.selectData;
for (let j = 0; j < selectData.length; j++) {
if (value === selectData[j].key) {
renderer = selectData[j].value;
}
}
}
}
return renderer || value;
}
},
created() {
for (let i = 0; i < this.tableData.length; i++) {
this.$set(this.tableData[i], "$index$", i);
for (let j = 0; j < this.columnData.length; j++) {
if (this.notIncluded.length != 0) {
if (this.notIncluded.indexOf(this.columnData[j].prop) < 0) {
this.$set(this.tableData[i], "$edit$" + j, false);
}
} else {
this.$set(this.tableData[i], "$edit$" + j, false);
}
}
}
if (!(this.tableData && this.tableData.length))
for (let i = 0; i < this.initNum; i++) {
this.addRow();
}
}
}
</script>
<style lang="less" scoped>
.table-span {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

引用代码:

<template>
<div class="container">
<div class="content">
<EditTable :initNum="5" :fit="true" :tableData="tableData" :columnData="partitionColumns" />
</div>
</div>
</template>

<script>
import EditTable from '@/components/EditTable.vue'
export default {
components: {
EditTable
},
props: {},
computed: {},
data() {
return {
tableData: [],
//数据格式
partitionColumns: [{
label: '姓名',
// width:''
prop: "name",
attributes: {
type: "input"
}
}, {
label: '性別',
prop: "sex",
attributes: {
type: "select",
selectData: [{
key: '0',
value: '男'
}, {
key: '1',
value: '女'
}]
}
}, {
label: '手机',
prop: "phone",
attributes: {
type: "input"
}
}, {
label: '邮箱',
prop: "email",
attributes: {
type: "input"
}
}, {
label: '地址',
prop: "address",
attributes: {
type: "input"
}
}]
}
},
methods: {},
created() {},
mounted() {},
}
</script>

<style lang="less" scoped>
.container {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: hidden;
overflow-x: hidden;
overflow-y: hidden;
display: flex;
justify-content: center;
align-items: center;
}

.content {
width: 80%;
height: 60%;
position: relative;
margin: auto;
flex-shrink: 0;
margin: 0px 10px;
background-color: #FFFFFF;
}
</style>

现在代码大致就是这样,不过需要先安装右击菜单:cnpm install e-vue-contextmenu --save 。目前仅仅支持文本框和下拉框,其他的话看官们需要可以自己修改,本人为后端开发,前端是兴趣爱好,代码有不足之处,希望大家多多包涵,如果能帮助到大家,本人觉得非常荣幸

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: