vue实现element自定义新增、删除table表格的行,及可输入input及下拉框选择

table表格可新增、多项删除行、点击浏览树形结构、input框绑定、下拉框选择功能

下面是功能演示视频:

table表格演示

后面会把完整的demo代码附上,有需要的可跳过前面直接到后面复制代码。
(部分思路在网上搜的,是很多方法的集合,看到一个写得很好的博客但是我在历史记录里没找到,于是乎我自己写完项目后又重新写了个小demo,归纳一下为了日后我自己能回顾,如若能帮到部分人是我的荣幸,若是哪里有错误的地方请及时指正,我会第一时间测试修改的,避免误认子弟)

思路:

1.新增表格行(handleAddBtn):给表格数组(我这里是用tableData数组)push空的对象
2.删除行(handleDeleteBtn):
①首先要拿到对应的索引,即可以用表格的@selection-change="handleDetailSelectionChange"获取勾选的行;
②然后在删除的方法里判断用户勾选选择行的长度(我这里是用checkedDetail数组存储),长度若为0则表示没有选择,为了增加用户体验感给予提示即可;若长度大于0,遍历checkedDetail与tableData作比较(xh属性)相同的删除即可
3.可编辑行(showUpdate):拿到对应的索引并令其显示(this.showEdit[index] = true;网上说要用 $ set方法,否则页面状态不更新)
4.取消编辑(cancelUpdate):拿到对应的索引并令其隐藏(this.showEdit[index] = false;)

:若觉得一个一个点击触发操作里的编辑太麻烦,想要直接点击行就能够显示编辑的话,可以使用element表格中行的点击事件(cell-click),这个事件能拿到对应的row,之后在行的点击事件方法里调用编辑行的方法 (this.showUpdate(row.xh - 1, row)) 即可

1、点击新增table表格行

添加点击事件,在handleAddBtn方法中创建表格对象

<!--HTML部分:-->
<el-button type="success" icon="el-icon-plus" size="mini" @click="handleAddBtn">添加</el-button>
//点击新增更多
        handleAddBtn() {
            this.getaddress = "";	//临时存储用户地址
            let obj = {};	//创建空的对象
            obj.username = "";	//用户名称
            obj.mescode = "";	//账号
            obj.address = "";	//地址
            this.tableData.push(obj);	//在tableData表格数组中添加对象
        },
2、点击删除行,可多选

添加删除点击事件,handleDeleteBtn方法把对应多选选中的行删除

 <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDeleteBtn">删除</el-button>
//删除
        handleDeleteBtn() {
            if (this.checkedDetail.length == 0) {
                this.$alert("请先选择要删除的数据", "提示", {
                    confirmButtonText: "确定",
                });
            } else {
                this.$confirm("请是否确认删除该属性?", "提示", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                    callback: (action) => {
                        if (action === "confirm") {
                            let val = this.checkedDetail; //checkedDetail为表格多选选中的数组
                            val.forEach((val, index) => {
                                this.tableData.forEach((v, i) => {
                                    if (val.xh === v.xh) {
                                        this.tableData.splice(i, 1);
                                    }
                                });
                            });
                            this.$message({
                                message: "删除成功,记得保存修改喔!",
                                type: "success",
                            });
                            this.$refs.tb.clearSelection();
                            return;
                        } else {
                            this.$message({
                                message: "已取消删除操作",
                                type: "warning",
                            });
                            return;
                        }
                    },
                });
            }
        },
3.操作部分的编辑、确定、取消功能

这里的行需要拿到对应的index值,所以需要用slot-scope=“{row,$index}”;
showEdit是个空数组,用来控制对应的标签显示及隐藏的;
这里使用this. $set() 方法将对应索引的行改成true或false

<el-table-column header-align="center" align="center" width="100" label="操作">
    <template slot-scope="{row,$index}">	
         <el-button v-if="!showEdit[$index]" @click="showUpdate($index,row)" type="text" size="small">编辑</el-button>
         <el-button v-if="showEdit[$index]" @click="submit($index,row)" type="text" size="small" style="color: #85ce61;">确定</el-button>
         <el-button v-if="showEdit[$index]" @click="cancelUpdate($index)" type="text" size="small" style="color: red;">取消</el-button>
    </template>
</el-table-column>
	    //点击修改
        showUpdate(index, row) {
            console.log("index");
            this.showEdit[index] = true;	
            this.$set(this.showEdit, index, true); //这里要用$set方法,否则页面状态不更新
        },
        //提交修改
        submit(index, row) {
            console.log("index", index);
            this.tableData[index].address = this.getaddress.adrNAME;
            // this.tableData[index].username = this.getUser.label;
            console.log("tableData===submit", this.tableData);

            //发送请求,隐藏输入框
            this.$message({
                type: "success",
                message: "已缓存,记得点击保存提交修改喔!",
                duration: 888,
                onClose: () => {
                    this.$set(this.showEdit, index, false); //vue添加属性的方法
                },
            });
        },
        //取消修改
        cancelUpdate(index) {
            this.$confirm("取消修改?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(() => {
                    this.$set(this.showEdit, index, false);
                })
                .catch(() => {});
        },

enmmmm,大概就到这里吧,整理不易,难免有疏漏的地方,若有错误请指出,我将第一时间修改,下面附上完整代码

<!-- 可新增/删除table表格页面 -->
<template>
    <div>
        <el-button type="success" icon="el-icon-plus" size="mini" @click="handleAddBtn">添加</el-button>
        <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDeleteBtn">删除</el-button>

        <el-table :data="tableData" :header-cell-class-name="starAdd" :header-cell-style="{background:'rgb(113 167 228)',color:'#fff'}" :row-class-name="rowClassName" @selection-change="handleDetailSelectionChange" ref="tb" border style="width: 100%; cursor: pointer;">
            <el-table-column type="selection" align="center" width="50">
            </el-table-column>
            <el-table-column label="序号" align="center" prop="xh" width="50"></el-table-column>
            <el-table-column prop="username" align="center" :required="true" label="用户职位">
                <template slot-scope="{row,$index}">
                    <span>{{row.username}}</span>
                    <button @click="showoschoose($index,row)" style="float: right;margin-right: 3px;padding: 5px;" v-if="showEdit[$index]">浏览</button>
                    <!-- <el-input v-model="tableData[row.xh-1].username" v-if="showEdit[$index]" clearable></el-input> -->
                </template>
            </el-table-column>
            <el-table-column prop="mescode" align="center" :required="true" label="账号">
                <template slot-scope="{row,$index}">
                    <span v-if="!showEdit[$index]">{{row.mescode}}</span>
                    <el-input v-model="tableData[row.xh-1].mescode" v-if="showEdit[$index]" placeholder="请输入该用户的账号">
                        <i slot="prefix" class="el-input__icon el-icon-search"></i>
                    </el-input>
                </template>
            </el-table-column>
            <el-table-column prop="address" align="center" label="住址">
                <template slot-scope="{row,$index}">
                    <span v-if="!showEdit[$index]">{{row.address}}</span>
                    <!-- <el-input v-model="tableData[row.xh-1].address" v-if="showEdit[$index]" clearable></el-input> -->
                    <el-select v-model="tableData[row.xh-1].address" v-if="showEdit[$index]" placeholder="请选择住址" value-key='ID' @change="addressChange">
                        <el-option v-for="item in addressArray" :key="item.ID" :label="item.adrNAME" :value="item">
                        </el-option>
                    </el-select>
                </template>
            </el-table-column>
            <el-table-column header-align="center" align="center" width="100" label="操作">
                <template slot-scope="{row,$index}">
                    <el-button v-if="!showEdit[$index]" @click="showUpdate($index,row)" type="text" size="small">编辑</el-button>
                    <el-button v-if="showEdit[$index]" @click="submit($index,row)" type="text" size="small" style="color: #85ce61;">确定</el-button>
                    <el-button v-if="showEdit[$index]" @click="cancelUpdate($index)" type="text" size="small" style="color: red;">取消</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
            <el-input placeholder="输入关键字进行过滤" v-model="filterText">
            </el-input>
            <el-tree class="filter-tree" :data="treeData" :props="defaultProps" default-expand-all :filter-node-method="filterNode" ref="tree" @node-click="checkUser">
            </el-tree>
            <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="gerUserBtn">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
export default {
    components: {},
    data() {
        return {
            tableData: [],
            filterText: "",
            addressArray: [
                //用户选择住址部分
                {
                    ID: 1,
                    adrNAME: "北京",
                },
                {
                    ID: 2,
                    adrNAME: "杭州",
                },
                {
                    ID: 3,
                    adrNAME: "三亚",
                },
            ],
            treeData: [
                {
                    id: 1,
                    label: "爷爷家",
                    children: [
                        {
                            id: 4,
                            label: "父亲",
                            children: [
                                {
                                    id: 9,
                                    label: "儿子",
                                },
                                {
                                    id: 10,
                                    label: "小儿子",
                                },
                            ],
                        },
                    ],
                },
                {
                    id: 2,
                    label: "外婆家",
                    children: [
                        {
                            id: 5,
                            label: "妈妈",
                        },
                        {
                            id: 6,
                            label: "小姨",
                        },
                    ],
                },
                {
                    id: 3,
                    label: "奶奶家",
                    children: [
                        {
                            id: 7,
                            label: "叔叔",
                        },
                        {
                            id: 8,
                            label: "姑姑",
                        },
                    ],
                },
            ],
            defaultProps: {
                children: "children",
                label: "label",
            },
            checkedDetail: [],
            showEdit: [], //控制显示及隐藏
            showSetTable: true, //是否显示
            rowIstemp: [], //点击浏览后对应的行信息
            getaddress: [],
            getUser: [],
            dialogVisible: false,
            nowIndex: "",
        };
    },
    methods: {
        //表格的新增
        rowClassName({ row, rowIndex }) {
            row.xh = rowIndex + 1;
        },
        //单选框选中数据
        handleDetailSelectionChange(selection) {
            this.checkedDetail = selection;
        },
        //点击新增更多
        handleAddBtn() {
            this.getaddress = "";
            let obj = {};
            obj.username = "";
            obj.mescode = "";
            obj.address = "";
            obj.group = "";
            this.tableData.push(obj);
        },
        //删除
        handleDeleteBtn() {
            if (this.checkedDetail.length == 0) {
                this.$alert("请先选择要删除的数据", "提示", {
                    confirmButtonText: "确定",
                });
            } else {
                this.$confirm("请是否确认删除该属性?", "提示", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                    callback: (action) => {
                        if (action === "confirm") {
                            let val = this.checkedDetail;
                            val.forEach((val, index) => {
                                this.tableData.forEach((v, i) => {
                                    if (val.xh === v.xh) {
                                        this.tableData.splice(i, 1);
                                    }
                                });
                            });
                            this.$message({
                                message: "删除成功,记得保存修改喔!",
                                type: "success",
                            });
                            this.$refs.tb.clearSelection();
                            return;
                        } else {
                            this.$message({
                                message: "已取消删除操作",
                                type: "warning",
                            });
                            return;
                        }
                    },
                });
            }
        },
        //红色五角星提示
        starAdd(obj) {
            if (obj.columnIndex === 2 || obj.columnIndex === 3) {
                return "star";
            }
        },
        //点击修改
        showUpdate(index, row) {
            console.log("index");
            this.showEdit[index] = true;
            this.$set(this.showEdit, index, true); //这里要用$set方法,否则页面状态不更新
        },
        //取消修改
        cancelUpdate(index) {
            this.$confirm("取消修改?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(() => {
                    this.$set(this.showEdit, index, false);
                })
                .catch(() => {});
        },
        //提交修改
        submit(index, row) {
            console.log("index", index);
            this.tableData[index].address = this.getaddress.adrNAME;
            // this.tableData[index].username = this.getUser.label;
            console.log("tableData===submit", this.tableData);

            //发送请求,隐藏输入框
            this.$message({
                type: "success",
                message: "已缓存,记得点击保存提交修改喔!",
                duration: 888,
                onClose: () => {
                    this.$set(this.showEdit, index, false); //vue添加属性的方法
                },
            });
        },
        //住址选择的下拉框
        addressChange(e) {
            console.log("住址中选择中的e", e);
            this.getaddress = e;
        },
        //选择用户的点击事件
        showoschoose(index, row) {
            console.log("index", index);
            console.log("row", row);
            this.nowIndex = index;
            this.dialogVisible = true;
        },
        handleClose(done) {
            this.$confirm("确认关闭?")
                .then((_) => {
                    done();
                })
                .catch((_) => {});
        },
        //选中的后的点击回调事件
        checkUser(data) {
            console.log("data", data);
            this.getUser = data;
        },
        //选择人员后的确定点击事件
        gerUserBtn() {
            console.log("getUser", this.getUser);
            this.tableData[this.nowIndex].username = this.getUser.label;
            this.dialogVisible = false;
        },
        //树形结构的过滤
        filterNode(value, data) {
            if (!value) return true;
            return data.label.indexOf(value) !== -1;
        },
    },
    watch: {
        filterText(val) {
            this.$refs.tree.filter(val);
        },
    },
};
</script>
<style>
</style>

有任何问题欢迎指出,或者有其它更好的方法还请不吝讲述。

  • 17
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
好的,针对你的问题,我可以给你一些解决方案。 1. Vue实现input下拉框模糊搜索 你可以使用Vue的computed属性来实现下拉框的模糊搜索,代码如下: ```html <template> <div> <input type="text" v-model="search" @input="searchData" /> <ul> <li v-for="item in filteredData" :key="item.id">{{ item.name }}</li> </ul> </div> </template> <script> export default { data() { return { data: [ { id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }, { id: 3, name: 'Orange' }, { id: 4, name: 'Pineapple' }, { id: 5, name: 'Pear' }, ], search: '', }; }, computed: { filteredData() { const search = this.search.toLowerCase(); return this.data.filter((item) => item.name.toLowerCase().includes(search)); }, }, methods: { searchData() { // 搜索操作 }, }, }; </script> ``` 在这个例子中,我们使用data来存储所有的数据,然后使用search来存储搜索关键字。在computed中,我们使用filteredData来过滤数据,只展示与搜索关键字匹配的数据。 2. IOS的keyup兼容性问题解决 在IOS中,keyup事件可能不会触发,而是会触发input事件。为了解决这个问题,我们可以使用v-model来绑定输入框的值,然后使用watch来监听输入框的变化,代码如下: ```html <template> <div> <input type="text" v-model="search" /> </div> </template> <script> export default { data() { return { search: '', }; }, watch: { search(val) { // 输入操作 }, }, }; </script> ``` 在这个例子中,我们使用v-model来绑定输入框的值,然后使用watch来监听search的变化。这样无论是在IOS还是其他设备上,都可以监听输入框的变化了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值