vue自定义指令表格多选

4 篇文章 0 订阅
1 篇文章 0 订阅
import Vue from 'vue'
import xhtml from '../service/xhtml'
// 判断全选类型在输入表格还是输出表格
const isInput = function(modifiers){
    return modifiers.input
}
// 解析表达式的值
let getExpression = function(expression){
    let expressionArr = expression.replace(/^{|}$/g,"").split(",")
    let expressionObj = {};
    expressionArr.forEach(element => {
        const [key,value] = element.split(":")
        expressionObj[key] = value
    });
    return expressionObj
}
// 自定义后缀名
const suffix={
    element:"Check"  //是否选中
}
// 检查是否当前数据全部被选中了
const checkIsAll = function(list,baseKey){
    return list.every(item=>{
        return item[baseKey+suffix.element]
    })
}
// 对返回的数据进行处理
const callbackDataFilter = function(data,specialKey){
    return data.filter((item,index)=>{
        return item[specialKey]
    })
}
// 对于输出表格获取当前对象唯一标志
const getUniqueKeyStr = function(el,item){
    let uniquValueArr = [];
    el.__uniqueKey__.forEach(key=>{
        uniquValueArr.push(item[key])
    })
    return uniquValueArr.join("");
}
// 对于输出表格进行数据保存处理逻辑
const outPutTableDataHandle = function(el,filterDataArr){
    filterDataArr.forEach((filterData)=>{
        let filterDataKey = getUniqueKeyStr(el,filterData)
        if(!el.__OUT_PUT_TABLE_OBJ__[filterDataKey]){
            el.__OUT_PUT_TABLE_OBJ__[filterDataKey] = filterData;
        }
    })
    return el.__OUT_PUT_TABLE_OBJ__
}
// 单选--定义改变传递数据前将outPutTableDataHandle值删除,防止回显问题
const changeOutPutTableDataHandle = function(el,item,check){
    let uniqueKeyStr = getUniqueKeyStr(el,item)
    if(!check&&el.__OUT_PUT_TABLE_OBJ__[uniqueKeyStr]){
        delete el.__OUT_PUT_TABLE_OBJ__[uniqueKeyStr]
    }
    return  el.__OUT_PUT_TABLE_OBJ__
}
// 全选--定义改变传递数据前将outPutTableDataHandle值删除,防止回显问题
const changeOutPutTableDataAllHandle = function(el,list,check){
    list.forEach((item)=>{
        let itemKey = getUniqueKeyStr(el,item)
        if(!check&&el.__OUT_PUT_TABLE_OBJ__[itemKey]){
            delete el.__OUT_PUT_TABLE_OBJ__[itemKey]
        }
    })
    return el.__OUT_PUT_TABLE_OBJ__
}
Vue.directive('tableCheck', {
    
    bind:function(el,binding){
        /**
         * 初始化对于基本信息获取
         * */ 
        // 判断是输入表格还是输出表格
        isInput(binding.modifiers)?el.__IS_INPUT__ = true:el.__IS_INPUT__ = false
        // 对于输出表格获取唯一key,翻页进行返显,生成保存数据数组
        !el.__IS_INPUT__?el.__uniqueKey__ = binding.value.uniqueKey:""
        !el.__IS_INPUT__?el.__OUT_PUT_TABLE_OBJ__ = {}:""
        // 解析表达式的值
        let expression = getExpression(binding.expression)
        el.__expression__ = expression
        // 保存基础key值,避免后续重复
        el.__baseKey__ = expression.list.replace(/\./g,"")
        el.__specialKeyCheck__ = el.__baseKey__+suffix.element
        
        if(binding?.value?.list){
            el.__list__ = binding.value.list
            el.__list__.map(function(item){
                item[el.__specialKeyCheck__] = false
            })
        }

        // 定义点击事件
        const checkItemClickHandle = function(event){
            let index = this.getAttribute("_index_")
            el.__list__[index][el.__specialKeyCheck__] = this.checked
            if(checkIsAll(el.__list__,el.__baseKey__)){
                el.__iSign__.classList.remove("unselect")
                el.__iSign__.classList.add("select")
            }else{
                el.__iSign__.classList.remove("select")
                el.__iSign__.classList.add("unselect")
            }
            el.__iSign_false__.setAttribute('class', el.__iSign__.getAttribute('class'));
            // 回调函数赋值给页面
            el.__IS_INPUT__?"":el.__OUT_PUT_TABLE_OBJ__ = changeOutPutTableDataHandle(el,el.__list__[index],this.checked)
            let filterValue = callbackDataFilter(el.__list__,el.__specialKeyCheck__)
            el.__IS_INPUT__?"":el.__OUT_PUT_TABLE_OBJ__ = outPutTableDataHandle(el,filterValue)
            el.__IS_INPUT__?
                binding.value.callback(filterValue,el.__list__)
                :
                binding.value.callback(Object.values(el.__OUT_PUT_TABLE_OBJ__),el.__list__)
        }
        el.__checkItemClickHandle__ = checkItemClickHandle;
    },
    inserted: function (el, binding) {
        // 全选按钮
        let th_check_all = el.querySelector("th[check-all]")
        // 全选样式(图片)
        let iSign = th_check_all.querySelector("i")
        el.__iSign__ = iSign
        // 全选样式(图片 假)
        let iSign_false  = el._TR_DIV_DOM_.querySelector("i")
        el.__iSign_false__ = iSign_false
        // 生成选择节点
        let checkItemTd = el.getElementsByClassName("check-item")
        // 新增点击节点并添加事件
        Array.from(checkItemTd).forEach((item,index)=>{
            let checkItem = item.querySelector("input");
            // 单个元素点击触发
            xhtml.bind(checkItem,"click",el.__checkItemClickHandle__)
        })
        // 全选按钮点击触发
        xhtml.bind(th_check_all, 'click', function () {
            let isNotSelect = iSign.classList.contains("unselect")
            el.__list__ = el.__list__.map(item=>{
                item[el.__specialKeyCheck__] = isNotSelect?true:false;
                Array.from(checkItemTd).forEach((item,index)=>{
                    let checkItem = item.querySelector("input");
                    checkItem.checked = isNotSelect
                })
                return item;
            })
            if(isNotSelect){
                iSign.classList.remove("unselect")
                iSign.classList.add("select")
            }else{
                iSign.classList.remove("select")
                iSign.classList.add("unselect")
            } 
            iSign_false.setAttribute('class', iSign.getAttribute('class'));
            // 回调函数赋值给页面
            el.__IS_INPUT__?"":el.__OUT_PUT_TABLE_OBJ__ = changeOutPutTableDataAllHandle(el,el.__list__,isNotSelect)
            let filterValue = callbackDataFilter(el.__list__,el.__specialKeyCheck__)
            el.__IS_INPUT__?"":el.__OUT_PUT_TABLE_OBJ__ = outPutTableDataHandle(el,filterValue)
            el.__IS_INPUT__?
                binding.value.callback(filterValue,el.__list__)
                :
                binding.value.callback(Object.values(el.__OUT_PUT_TABLE_OBJ__),el.__list__)
        })
    },
    update: function (el, binding) {
        // 数据dom改变,数据改变,对于分页  情况进行数据回显
        el.__list__ = binding.value.list
        el.__update__ = false;
        if(!el.__IS_INPUT__&&el.__list__){
            el.__list__ = el.__list__.map((item)=>{
                if(item[el.__specialKeyCheck__]===undefined){
                    el.__update__ = true;
                }
                let uniqueKeyStr = getUniqueKeyStr(el,item)
                if(el.__OUT_PUT_TABLE_OBJ__[uniqueKeyStr]){
                    item[el.__specialKeyCheck__] = true
                }else{
                    item[el.__specialKeyCheck__] = false
                }
                return item
            })
            if(el.__update__){
                binding.value.callback(undefined,JSON.parse(JSON.stringify(el.__list__)))
            }
            // 校验是否全部选中了
            if(checkIsAll(el.__list__,el.__baseKey__)){
                el.__iSign__.classList.remove("unselect")
                el.__iSign__.classList.add("select")
            }else{
                el.__iSign__.classList.remove("select")
                el.__iSign__.classList.add("unselect")
            }
            el.__iSign_false__.setAttribute('class', el.__iSign__.getAttribute('class'));
            // 对于输出表格获取不到数据行点击单元,在这里再进行处理
            let checkItemTd = el.getElementsByClassName("check-item")
            if(checkItemTd.length!=0){
                // 新增点击节点并添加事件
                Array.from(checkItemTd).forEach((item,index)=>{
                    let checkItem = item.querySelector("input");
                    // 先清除点击事件
                    xhtml.unbind(checkItem,"click",el.__checkItemClickHandle__)
                    // 单个元素点击触发
                    xhtml.bind(checkItem,"click",el.__checkItemClickHandle__)
                })
            }
        }
    },
});

  1. 无分页输入表格用法
 <table v-table-title="{list:params.flist1}"
        v-table-check.input="{list:params.flist1,callback:paramsflist1CallBack}"
       v-col-resize >
       <thead>
           <tr>
               <th check-all>
                   <i class="unselect check-all"></i>全选
               </th>
               <th>序号</th>
               <th order='{"column":"vouKind","type":"NUMBER"}'>凭证种类</th>
               <th>分行代码</th>
               <th>凭证批号</th>
               <th>凭证单位</th>
               <th>数量</th>
               <th>起始凭证序号</th>
               <th>终止凭证序号</th>
               <th>终止凭证序号</th>
               <th>终止凭证序号</th>
               <th>终止凭证序号</th>
               <th>终止凭证序号</th>
               <th>终止凭证序号</th>
               <th>凭证数</th>
           </tr>
       </thead>
       <tbody>
           <tr v-for="(item,index) in params.flist1" :key="index">
           <td class="check-item">
               <input type="checkbox" :_index_="index" v-model="item.paramsflist1Check"/>
           </td>
           <td>{{item.paramsflist1Check}}</td>
           <td><input type="text" v-select='selectList.VouKind_7101' @blur='blur4854346231($event.target,index)' @keypress.enter.prevent='enter4854346231($event.target,index)' v-model="item.vouKind"  :disabled='false' validate-name='凭证种类' v-input-check='[params.vouKind,"select"]'/></td>
           <td><input type="text"  @blur='blur1745662513($event.target,index)' @keypress.enter.prevent='enter1745662513($event.target,index)' v-model="item.subBrnCd"  :disabled='false' validate-name='分行代码' v-input-check='[params.subBrnCd,""]'/></td>
           <td><input type="text"   @keypress.enter.prevent='enter2626388134($event.target,index)' v-model="item.vouBatchNo"  :disabled='false' validate-name='凭证批号' v-input-check='[params.vouBatchNo,""]'/></td>
           <td><input type="text" v-select='selectList.VouUnitCd'  @keypress.enter.prevent='enter2317186231($event.target,index)' v-model="item.vouUnitCd"  :disabled='false' validate-name='凭证单位' v-input-check='[params.vouUnitCd,"select"]'/></td>
           <td><input type="text"   @keypress.enter.prevent='enter5454808410($event.target,index)' v-model="item.count"  :disabled='false' validate-name='数量' v-input-check='[params.count,""]'/></td>
           <td><input type="text"   @keypress.enter.prevent='enter5524352968($event.target,index)' v-model="item.begingVouSeqNo"  :disabled='false' validate-name='起始凭证序号' v-input-check='[params.begingVouSeqNo,""]'/></td>
           <td><input type="text"  @blur='blur7690199946($event.target,index)' @keypress.enter.prevent='enter7690199946($event.target,index)' v-model="item.endVouSeqNo"  :disabled='false' validate-name='终止凭证序号' v-input-check='[params.endVouSeqNo,""]'/></td>
           <td><input type="text"  @blur='blur7690199946($event.target,index)' @keypress.enter.prevent='enter7690199946($event.target,index)' v-model="item.endVouSeqNo"  :disabled='false' validate-name='终止凭证序号' v-input-check='[params.endVouSeqNo,""]'/></td>
           <td><input type="text"  @blur='blur7690199946($event.target,index)' @keypress.enter.prevent='enter7690199946($event.target,index)' v-model="item.endVouSeqNo"  :disabled='false' validate-name='终止凭证序号' v-input-check='[params.endVouSeqNo,""]'/></td>
           <td><input type="text"  @blur='blur7690199946($event.target,index)' @keypress.enter.prevent='enter7690199946($event.target,index)' v-model="item.endVouSeqNo"  :disabled='false' validate-name='终止凭证序号' v-input-check='[params.endVouSeqNo,""]'/></td>
           <td><input type="text"  @blur='blur7690199946($event.target,index)' @keypress.enter.prevent='enter7690199946($event.target,index)' v-model="item.endVouSeqNo"  :disabled='false' validate-name='终止凭证序号' v-input-check='[params.endVouSeqNo,""]'/></td>
           <td><input type="text"  @blur='blur7690199946($event.target,index)' @keypress.enter.prevent='enter7690199946($event.target,index)' v-model="item.endVouSeqNo"  :disabled='false' validate-name='终止凭证序号' v-input-check='[params.endVouSeqNo,""]'/></td>
           <td><input type="text"   @keypress.enter.prevent='enter3456884269($event.target,index)' v-model="item.vouSheetsNum"  :disabled='false' validate-name='凭证数' v-input-check='[params.vouSheetsNum,""]'/></td>
       </tr>
       </tbody>
   </table>

2.有分页输出表格用法

 <table 
     v-table-title="{list:result.flist1}"
     v-table-check.output="{list:result.flist1,callback:resultflist1CallBack,uniqueKey:['tellJnno','payeeNm','payeeOpengBkBkNm']}"
     v-col-resize
     >
         <thead>
             <tr>
                 <!-- <th>序号</th> -->
                 <th check-all>
                     <i class="unselect check-all"></i>全选
                 </th>
                 <th order='{"column":"custno","type":"NUMBER"}'>客户号</th>
                 <th order='{"column":"psnlNm","type":"STRING"}'>个人名称</th>
                 <th order='{"column":"certKind","type":"NUMBER"}'>证件种类</th>
                 <th order='{"column":"certNo","type":"NUMBER"}'>证件号码</th>
                 <th order='{"column":"certValtPrid","type":"DATE"}'>证件到期日期</th>
                 <th order='{"column":"gender","type":"NUMBER"}'>性别</th>
                 <th order='{"column":"tellJnno","type":"NUMBER"}'>交易编号</th>
                 <th order='{"column":"payeeNm","type":"STRING"}'>收款方户名</th>
                 <th order='{"column":"payeeOpengBkBkNm","type":"STRING"}'>收款方开户行名称</th>
             </tr>
         </thead>
         <tbody>
             <tr v-for="(item,index) in result.flist1" :key="index">
                 <!-- <td>{{(pageParams.doSubmit_pageIndex-1)*pageParams.doSubmit_pageNum+index+1}}</td> -->
                 <td class="check-item">
                     <input type="checkbox" :_index_="index" v-model="item.resultflist1Check"/>
                 </td>
                 <td><span>{{item.custno}}--{{item.resultflist1Check}}</span></td>
                 <td><span>{{item.psnlNm}}</span></td>
                 <td><span>{{item.certKind}}-{{selectList.CertKind[item.certKind]}}</span></td>
                 <td><span>{{item.certNo}}</span></td>
                 <td><span>{{item.certValtPrid|dateTime('yyyy/MM/dd')}}</span></td>
                 <td><span>{{item.gender}}-{{selectList.Gender[item.gender]}}</span></td>
                 <td><span>{{item.tellJnno}}</span></td>
                 <td><span>{{item.payeeNm}}</span></td>
                 <td><span>{{item.payeeOpengBkBkNm}}</span></td>
             </tr>
         </tbody>
     </table>

相关素材
未选中
选中
tip:
xhtml为相关dom基础操作
记得还有回调函数哦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 中实现表格多选行数据,一般有两种方式: 1. 使用 Checkbox 实现:在每一行数据前添加一个 Checkbox,然后将选中的行的数据存储到一个数组中。具体实现可以参考以下代码: ```html <template> <div> <table> <thead> <tr> <th> <input type="checkbox" v-model="allChecked" @change="checkAll" /> </th> <th>ID</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <tr v-for="(item, index) in list" :key="item.id"> <td> <input type="checkbox" v-model="checkedList" :value="item" /> </td> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.age }}</td> </tr> </tbody> </table> </div> </template> <script> export default { data() { return { list: [ { id: 1, name: "Tom", age: 18 }, { id: 2, name: "Jerry", age: 20 }, { id: 3, name: "Mike", age: 22 } ], checkedList: [], allChecked: false }; }, methods: { checkAll() { if (this.allChecked) { this.checkedList = [...this.list]; } else { this.checkedList = []; } } } }; </script> ``` 2. 使用表格的 row-click 事件实现:在表格中添加一个 row-click 事件,当用户选中某一行时,将该行的数据存储到一个数组中。具体实现可以参考以下代码: ```html <template> <div> <table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <tr v-for="(item, index) in list" :key="item.id" @click="handleClick(item)"> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.age }}</td> </tr> </tbody> </table> </div> </template> <script> export default { data() { return { list: [ { id: 1, name: "Tom", age: 18 }, { id: 2, name: "Jerry", age: 20 }, { id: 3, name: "Mike", age: 22 } ], checkedList: [] }; }, methods: { handleClick(item) { const index = this.checkedList.findIndex(i => i.id === item.id); if (index > -1) { this.checkedList.splice(index, 1); } else { this.checkedList.push(item); } } } }; </script> ``` 这两种方式都可以实现表格多选行数据,具体选择哪种方式可以根据实际情况进行选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值