vue实现树形table表格展示

导读:本篇文章讲解 vue实现树形table表格展示,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

由于element文档实在是太坑了,没有这方面的代码,索性自己查阅了一堆源码之后,才终于在不使用自定义组件的情况下,写出了treeTable的展示界面,以下是代码,仅供参考,有些数据是要联系到后台之类的,我就没给出,所以参考的小伙伴记得自行替换报错的页面代码

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2019/4/17
  Time: 15:23
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>合同付款详情</title>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
	<script src="/static/plugins/vuejs/vue.js" type="text/javascript"></script>
	<!-- 引入样式 -->
	<link rel="stylesheet" href="/static/plugins/elementui/lib/theme-chalk/index.css">
	<!-- 引入组件库 -->
	<script src="/static/plugins/elementui/lib/index.js"></script>
	<%--路由--%>
	<script src="/static/plugins/vuejs/vue-router.js" type="text/javascript"></script>
	<%--axios--%>
	<script src="/static/plugins/vuejs/axios.js" type="text/javascript"></script>
</head>
<body>
<div id="app">
    <%--高级查询--%>
    <el-row style="margin:10px 0px;background-color: #FCFCFC;height:60px;line-height: 60px;border:1px solid #e6e6e6">
        <el-col :span="16" style="padding-left:15px">
            <span style="font-size: 15px">合同编号:</span>
            <el-input size="small" style="width:120px" v-model="queryParam.keyword" placeholder="请输入编号"></el-input>
            <span style="font-size: 15px;margin-left: 10px">付款时间:</span>
            <el-date-picker size="small"
                            v-model="queryParam.beginDate"
                            align="right"
                            type="date" value-format="yyyy-MM-dd"
                            placeholder="选择日期"
                            style="width:130px">
            </el-date-picker>
            到
            <el-date-picker
                    style="width:130px"
                    size="small"
                    v-model="queryParam.endDate"
                    align="right"
                    type="date" value-format="yyyy-MM-dd"
                    placeholder="选择日期">
            </el-date-picker>
        </el-col>
        <el-col :span="26">
            <el-button round size="small" type="primary" icon="el-icon-search" @click="serach">搜索</el-button>
            <el-button round size="small" type="success" icon="el-icon-refresh" @click="clearQueryParam">刷新</el-button>
            <el-button round size="small" type="warning" icon="el-icon-document" @click="handlExport">导出</el-button>
            <el-button round size="small" type="danger" icon="el-icon-delete" @click="DeleteAll">删除</el-button>

        </el-col>
    </el-row>
    <el-table
            v-loading="loading"
            element-loading-text="正在拼命加载,请稍等片刻 ~o( =∩ω∩= )m"
            element-loading-spinner="el-icon-loading" :row-class-name="tableRowStyle"
            element-loading-background="rgba(0, 0, 0, 0.8)" @selection-change="selectMore" size="mini"
            height="330" :data="contractDetails" style="width: 100%" :stripe="true" :border="true">
        <el-table-column align="center" type="selection" prop="id"></el-table-column>
        <el-table-column align="center" label="所属合同编号" width="200" prop="contract.sn">
            <template slot-scope="scope">
                <div @click="treeClick(scope.row,scope.$index)" style="cursor: pointer;">
                    <template v-if="scope.row.children && scope.row.children.length > 0">
                        <div slot="reference" class="name-wrapper">
                            <el-tag type="warning" style="font-size: 15px;">{{ scope.row.contract.sn }}</el-tag>
                        </div>
                        <i class="el-icon-caret-bottom" :style="'margin-left:'+(scope.row.level-1)*2+'em;'"
                           v-if="scope.row.open"></i>
                        <i class="el-icon-caret-top" :style="'margin-left:'+(scope.row.level-1)*2+'em;'" v-else></i>
                    </template>
                    <div v-else slot="reference" class="name-wrapper">
                        <el-tag style="font-size: 15px;">{{ scope.row.contract.sn }}</el-tag>
                    </div>
                </div>
            </template>
        </el-table-column>
        <el-table-column align="center" label="付款时间" width="160" prop="payTime" :sortable="true"></el-table-column>
        <el-table-column align="center" label="付款金额" prop="money" :sortable="true">
            <template slot-scope="scope">
                <el-tag type="success" style="font-size: 15px;" disable-transitions>
                    {{scope.row.money|myMoney('¥','元')}}
                </el-tag>
            </template>
        </el-table-column>
        <el-table-column align="center" label="合同金额" prop="lastMoney" >
            <template slot-scope="scope">
                <el-tag type="warning" style="font-size: 15px;" disable-transitions>
                    {{scope.row.lastMoney|myMoney('¥','元')}}
                </el-tag>
            </template>
        </el-table-column>
        <el-table-column align="center" label="付款比例" prop="percent" :sortable="true">
            <template slot-scope="scope">
                <el-tag type="primary" style="font-size: 15px;" disable-transitions>
                    {{scope.row.percent|myPercent}}
                </el-tag>
            </template>
        </el-table-column>
        <el-table-column align="center" label="是否付清" prop="isPayment"
                         :filters="[{ text: '未付清', value: '1' }, { text: '已付清', value: '0' }]"
                         :filter-method="filterTag"
                         filter-placement="bottom-end">
            <template slot-scope="scope">
                <el-tag
                        :type="scope.row.isPayment| statusFilter"
                        disable-transitions>{{scope.row.isPayment|formatStata}}
                </el-tag>
            </template>
        </el-table-column>
        <el-table-column align="center" label="操作">
            <template slot-scope="scope">
                <el-button size="mini" type="primary" style="margin-left: 25px" icon="el-icon-edit" round
                           @click="handleEdit(scope.$index, scope.row)">编辑
                </el-button>
                <el-button size="mini" style="margin-top: 5px" type="success" icon="el-icon-circle-plus-outline" round
                           @click="handleAdd(scope.$index, scope.row)">追加详情
                </el-button>
            </template>
        </el-table-column>
    </el-table>
    <div class="block">
        <el-pagination @size-change="handleSizeChange" @current-change="handlePageChange"
                       layout="total, sizes, prev, pager, next, jumper" :current-page="page"
                       :page-sizes="[5, 10, 20]"
                       :page-size="100" :total="total">
        </el-pagination>
    </div>
    <!--付款详情模态框-->
    <el-dialog title="追加/编辑付款详情" :close-on-click-modal="false" :visible.sync="openDetail" width="35%">
        <el-form ref="formDt" :rules="rules" :model="detail" label-width="100px">
            <el-input v-model="detail.id" type="hidden"></el-input>
            <el-input v-model="detail.contract_Id" type="hidden"></el-input>
            <el-form-item label="合同编号:">
                <el-input :readonly="true" v-model="detail.sn"></el-input>
            </el-form-item>
            <el-form-item label="付款时间:" prop="payTime">
                <el-date-picker
                        v-model="detail.payTime"
                        type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
                        placeholder="选择日期">
                </el-date-picker>
            </el-form-item>
            <el-form-item label="付款金额:" prop="money">
                <el-input v-model.number="detail.money"></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button @click="openDetail = false">取 消</el-button>
            <el-button type="primary" @click="subDetail('formDt')">提交</el-button>
        </span>
    </el-dialog>

</div>
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            //校验字段
            rules: {
                money: [{
                    required: true,
                    message: '请输入金额!!',
                    trigger: 'blur'
                }, {
                    type: 'number',
                    message: '必须为数字类型!!',
                    trigger: 'blur'
                }],
                payTime: [{
                    required: true,
                    message: '请选择时间!!',
                    trigger: 'blur'
                }]
            },
            checks: [],
            detail: {
                id: '',
                contract_Id: '',
                parent_Id: '',
                payTime: '',
                money: '',
                lastMoney: '',
                percent: '',
                isPayment: ''
            },
            queryParam: {
                keyword: null,
                beginDate: null,
                endDate: null
            },
            contractDetails: [],
            //分页数据
            page: 1,
            rows: 5,
            total: 0,
            loading: false,
            openDetail: false,
            openDisabled: false
        },
        methods: {
            //表格样式
            tableRowStyle({row, rowIndex}) {
                if (rowIndex / 2 == 0) {
                    return 'warning-row';
                } else {
                    return 'success-row';
                }
                return '';
            },
            //高级查询(多条件查询)
            serach() {
                this.loadContractDetails();
            },
            //清空查询条件
            clearQueryParam() {
                this.queryParam = {};
                //重新加载数据
                this.loadContractDetails();
            },
            //导出文件为Excel
            handlExport() {
                location.href = "ContractDetails/export";
            },
            //处理数据格式以便于树形菜单展示
            treeTableXcode: function (data, xcode) {
                xcode = xcode || "";
                for (var i = 0; i < data.length; i++) {
                    var item = data[i];
                    item.xcode = xcode + i;
                    if (item.children && item.children.length > 0) {
                        this.treeTableXcode(item.children, item.xcode + "-");
                    }
                }
            },
            //展示树形结构数据
            treeClick: function (item, index) {
                if (item.open) {
                    this.collapse(item, index);
                } else {
                    this.expand(item, index);
                }
            },
            expand: function (item, index) {
                if (!item.children) {
                    return index;
                }
                //展开
                for (var i = 0; item.children && i < item.children.length; i++) {
                    var child = item.children[i];
                    this.contractDetails.splice(++index, 0, child);
                    if (child.children && child.children.length > 0 && child.open) {
                        index = this.expand(child, index);
                    }
                }
                item.open = true;
                return index;
            },
            //收回
            collapse: function (item, index) {
                if (!item.children) {
                    return index;
                }
                //收缩
                item.open = false;
                var len = 0;
                for (var i = index + 1; i < this.contractDetails.length; i++) {
                    var xcode = this.contractDetails[i].xcode;
                    if (xcode.startsWith(item.xcode + "-")) {
                        len++;
                    } else {
                        break;
                    }
                }
                this.contractDetails.splice(index + 1, len);
            },
            //筛选付款状态
            filterTag(value, row) {
                return row.isPayment == value;
            },
            loadContractDetails() {
                this.loading = true;
                //请求参数
                this.queryParam.page = this.page;
                this.queryParam.rows = this.rows;
                //发送异步请求加载数据赋值
                axios.get('ContractDetails/page', {
                    //get方式传参
                    params: this.queryParam
                }).then((res) => {
                    //成功后的回调
                    let data = res.data;
                    if (data.rows) {
                        this.contractDetails = data.rows;
                        this.total = data.total;
                        this.treeTableXcode(this.contractDetails)
                        this.loading = false;
                    }
                });
            },
            //分页处理
            handlePageChange(currentPage) {
                this.page = currentPage;
                //重新加载数据
                this.loadContractDetails();
            },
            handleSizeChange(val) {
                this.rows = val;
                //重新加载数据
                this.loadContractDetails();
            },
            //追加
            handleAdd(index, row) {
                if(row.parent_Id > 0){
                    this.$message.error('请在父级数据上追加付款详情!!');
                }else{
                    this.detail = {};
                    this.detail.sn = row.contract.sn;
                    this.detail.contract_Id = row.contract_Id;
                    this.detail.parent_Id = row.id;
                    this.detail.lastMoney = row.lastMoney;
                    this.openDetail = true;
                    //重新加载数据
                    this.loadContractDetails();
                }
            },
            //编辑
            handleEdit(index, row) {
                this.detail = row;//将当前数据填入模态框
                this.detail.sn = row.contract.sn;
                this.detail.afterMoney = this.detail.money;
                this.openDetail = true;
                //重新加载table
                this.loadContractDetails();
            },
            subDetail(formName) {
                if (this.detail.money > this.detail.sumMoney) {
                    this.$message.error('付款金额不能大于合同金额!!');
                    return null;
                } else {
                    this.$refs[formName].validate((valid) => {
                        if (valid) {
                            this.detail.percent = this.detail.money / this.detail.lastMoney * 100;
                            m = this.detail.lastMoney - this.detail.money;
                            if (m > 0) {
                                this.detail.isPayment = '1';
                            } else {
                                this.detail.isPayment = '0';
                            }
                            //发送异步请求加载数据赋值给details
                            axios.post('ContractDetails/save',
                                //post方式传参
                                this.detail
                            ).then((res) => {
                                //成功后的回调
                                let data = res.data;
                                if (data.success) {
                                    this.$message({
                                        type: 'success',
                                        message: data.message
                                    });
                                    //重新加载table
                                    this.loadContractDetails();
                                    this.openDetail = false;
                                } else {
                                    this.$message.error(data.message);
                                }
                            })
                        } else {
                            this.$message.error('请输入正确的数据!!');
                            return false;
                        }
                    })
                }
            },
            selectMore(val) {
                this.checks = val;
            },
            DeleteAll() {
                //获取所有选中行的id组成的字符串,以逗号分隔
                var ids = this.checks.map(item => item.id).join()
                this.$confirm('此操作将永久删除该合同下所有付款详情, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    //发送ajax执行删除操作
                    axios.post('ContractDetails/delete?ids=' + ids).then((res) => {
                        //成功后重新加载表格
                        let data = res.data;
                        if (data.success) {
                            this.$message({
                                type: 'success',
                                message: data.message
                            });
                            //重新加载table
                            this.loadContractDetails();
                        } else {
                            this.$message.error(data.message);
                        }
                    })
                })
            }
        },
        mounted() {
            this.loadContractDetails();
        },
        //过滤器
        filters: {
            //展示是否付款的状态
            statusFilter(status) {
                const statusMap = {
                    0: 'success',
                    1: 'danger'
                }
                return statusMap[status]
            },
            // 状态显示转换
            formatStata(status) {
                const statusMap = {
                    0: '已付清',
                    1: '未付清'
                }
                return statusMap[status]
            },
            //金额展示处理
            myMoney: function (myInput, arg1, arg2) {
                var money = arg1 + myInput + arg2;
                return money;
            },
            //百分比处理展示
            myPercent: function (myInput) {
                return myInput + "%";
            }
        }
    })
</script>
<style>
    .el-table .warning-row {
        background: oldlace;
    }

    .el-table .success-row {
        background: #f0f9eb;
    }
</style>
</body>
</html>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/75164.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!