自定义transfer组件(基于vue3 ts element ui 稍微改改都能用)

注意 类名使用的是全局定义的类名 flex 为 display:flex, align-center为align-items:center, p-10为 padding: 10px; w-100为width:100%; f16 font-size:16px; 依次类推

<template>
  <!-- 手动穿梭框 -->
  <div class="flex align-center justify-between" :style="alterStyle" @click="data.setBtnKey = NaN">
    <!-- 左边内容 -->
    <div class="border radius-5 hidden" :style="leftRightStyle">
      <!-- 头部选中 -->
      <div
        class="
          w-100
          border-bottom
          p-10
          flex
          align-center
          justify-between
          box-sizing
        "
        style="height: 40px; background: #f5f7fa"
      >
        <div class="flex align-center">
          <el-checkbox
            v-model="data.leftSelectAll"
            :disabled="data.whetherCan ? true : !data.leftData.length"
            @change="leftAllCheckbx"
            :indeterminate="
              data.leftSelectAll ? false : Boolean(data.leftSelectLength)
            "
          >
          </el-checkbox>
          <p class="f16 ml-10">{{ titles[0] }}</p>
        </div>
        <p class="f12">
          {{ data.leftSelectLength }}/{{ data.allDataList.length }}
        </p>
      </div>

      <!-- 搜索框 -->
      <div class="w-100 p-10">
        <el-input
          v-model="data.leftSearchText"
          @input="leftSearch"
          clearable
          placeholder="请输入搜索内容"
        >
        </el-input>
      </div>

      <!-- 内容 -->
      <div class="p-10 scrollEvent" style="overflow: auto; height: 300px">
        <div class="hidden-scroll mb-10" v-show="data.leftData.length">
          <div
            v-for="item in data.leftData"
            class="flex align-center"
            :key="item[showKeyVal.key]"
          >
            <el-checkbox
              v-model="item.checkbox"
              :disabled="item.disabled"
              @change="leftRadioSelect(item, 'notSet')"
              :checked="item.checkbox"
            ></el-checkbox>
            <p
              class="ml-10 cp outText"
              @click="leftRadioSelect(item)"
              :style="item.checkbox === true ? 'color:#409eff' : ''"
            >
             <p class="labelText">{{ item[showKeyVal.label] }}</p>
            </p>
          </div>
        </div>

        <div
          v-show="!data.leftData.length"
          class="w-100 flex align-center justify-center"
        >
          <p>暂无数据</p>
        </div>
      </div>
    </div>

    <!-- 按钮 -->
    <div class="flex algin-center flex-column">
      <el-button
        type="primary"
        class="mb-10"
        :disabled="Boolean(!data.leftSelectLength)"
        @click="clickIncident('goto')"
      >
        {{ butText[1] }}
        <el-icon><ArrowRight /></el-icon>
      </el-button>
      <el-button
        type="primary"
        style="margin: 0"
        :disabled="Boolean(!data.rightSelectLength)"
        @click="clickIncident('back')"
      >
        <el-icon><ArrowLeft /></el-icon>
        {{ butText[0] }}
      </el-button>
    </div>

    <!-- // 右侧内容 -->
    <div class="border radius-5 hidden" :style="leftRightStyle">
      <!-- // 头部选中 -->
      <div
        class="
          w-100
          border-bottom
          p-10
          flex
          align-center
          justify-between
          box-sizing
        "
        style="height: 40px; background: #f5f7fa"
      >
        <div class="flex align-center">
          <el-checkbox
            v-model="data.rightSelectAll"
            @change="rightAllCheckbx"
            :disabled="data.rightSearchText? !data.rightSearchData.length : !data.rightData.length"
            :indeterminate="
              data.rightSelectAll ? false : Boolean(data.rightSelectLength)
            "
          >
          </el-checkbox>
          <p class="f16 ml-10">{{ titles[1] }}</p>
        </div>
        <p class="f12">
          {{ data.rightSelectLength }}/{{ data.rightData.length }}
        </p>
      </div>

      <!-- // 搜索框 -->
      <div class="w-100 p-10">
        <el-input
          v-model="data.rightSearchText"
          @input="rightSearch"
          placeholder="请输入搜索内容"
          clearable
        >
        </el-input>
      </div>

      <!-- // 内容 -->
      <div class="p-10 scrollEvent" style="overflow: auto; height: 300px" @contextmenu="preventEvent($event)">
        <div style="min-height: 200px" class="hidden-scroll" v-show="data.rightSearchText? data.rightSearchData.length: data.rightData.length">
          <div
            v-for="item in data.rightSearchText
              ? data.rightSearchData
              : data.rightData"
            class="flex align-center"
            :key="item[showKeyVal.key]"
            @mouseup="rightClick($event, item)"
          >
            <el-checkbox
              v-model="item.checkbox"
              @change="rightRadioSelect(item, 'notSet')"
              :checked="item.checkbox"
            ></el-checkbox>
            <p
              class="ml-10 cp outText w-100"
              :style="item.checkbox === true ? 'color:#409eff' : ''"
            >
              <p @click="rightRadioSelect(item)" class="labelText">{{ item[showKeyVal.label] }}</p>
              <span v-show="data.labelShow === item[showKeyVal.key]" class="ml-10" style="color: red;">主单位</span>
              <!-- // 按钮 -->
              <p v-show="data.setBtnKey === item[showKeyVal.key]" @click="setHost" style="color: #3eacef">设为主单位</p>
            </p>
          </div>
          
        </div>
        <div
          v-show="data.rightSearchText? !data.rightSearchData.length : !data.rightData.length"
          class="w-100 flex align-center justify-center">
          <p>暂无数据</p>
        </div>

      </div>
    </div>
  </div>
</template>

全局定义的css样式我就不贴了 太多了

<style lang="scss" scoped>
.hidden-scroll::-webkit-scrollbar {
  display: none;
}
.outText {
  display: flex;
  overflow: hidden;
  align-items: center;
  text-overflow: ellipsis;
  justify-content: space-between;
}
.labelText{
  width: 130px;
  height: 36px;
  overflow: hidden;
    white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
<script lang="ts">
import { reactive } from "@vue/reactivity";
import { onMounted, onUnmounted, watch } from "@vue/runtime-core";
import { useRouter } from "vue-router";
export default {
  props: {
    alterStyle: {
      type: Object,
      default: () => {
        return {
          width: "1000px",
        };
      },
    }, // 主题样式
    leftRightStyle: {
      type: Object,
      default: () => {
        return {
          width: "300px",
          height: "400px",
        };
      },
    },
    // 主单位
    primaryUnit: {
      type: Number,
      default: NaN,
    },
    titles: {
      // 数据信息展示
      type: Array,
      default: () => {
        return ["所有单位", "派发单位"];
      },
    },
    butText: {
      // 按钮文字显示
      type: Array,
      default: () => {
        return ["左移", "右移"];
      },
    },
    whetherPaging: {
      // 默认打开分页 执行分页搜索查询
      type: Boolean,
      default: true,
    },
    selectDataUpdate: {
      // 选中数据是否跟随数据源更新 (默认更新)
      type: Boolean,
      default: true,
    },
    allData: {
      // 所有的数据
      type: Array,
      default: () => [],
    },
    showKeyVal: {
      // 对应的键值对(需要展示的)
      type: Object,
      default: () => {
        return {
          key: "id",
          label: "name",
        };
      },
    },
    selectData: {
      // 被选中的数据
      type: Array,
      default: () => {
        return []
      },
    },

    astrictList: {
      // 限制选中器
      type: Array,
      default: () => [],
    },

    showPageSize: {
      // 每页显示多少
      type: Number,
      default: 1000,
    },
  },
  setup(props, context) {

    // 数据集合
    let data = reactive({
      labelShow: NaN, // 主单位key
      setBtnKey: NaN, // 设置为主单位
      allDataList: <any>[], // 所有数据的拷贝(用于更改状态)
      showPageNum: 1, // 页数 (通过滚动添加)
      // 左侧
      leftData: <any>[], // 目前显示数据 // 左侧数据
      leftSearchText: "", // 左侧内容搜索
      leftSelectAll: false, // 左侧全选
      whetherCan: false, // 是否可用
      leftScrollEle: <any>"", // 滚动元素
      leftSelectLength: <number>0, // 被选中元素有多少条
      // 右侧
      rightData: <any>[], // 右侧数据
      rightDataCopy: <any>[], // 切换源也会保存数据 用于赋值
      rightSearchData: [], // 右侧数据备份 用于搜索恢复
      rightSearchText: "", // 右侧内容搜索
      rightSelectAll: false, // 右侧全选
      rigjtScorllEle: "", // 滚动元素
      rightSelectLength: 0, // 被选中元素有多少条
    });

    onMounted(() => {
      // 手动部分
      // left滚动监听
      if (props.whetherPaging) {
        data.leftScrollEle = document.querySelectorAll(".scrollEvent")[0];
        data.leftScrollEle.addEventListener("scroll", leftScroll, false);
      }
    });

    // 组件被销毁前
    onUnmounted(() => {
      if (props.whetherPaging) {
        data.leftScrollEle.removeEventListener("scroll", leftScroll);
      }
    });

    // 重新排序 目前按照id大小排序
    const sortFun = (obj: { [x: string]: number; }, obj1: { [x: string]: number; }) => {
      if (obj[props.showKeyVal.key] > obj1[props.showKeyVal.key]) {
        return 1;
      } else {
        return -1;
      }
    };

    // 刷新
    const refresh = () => {
      data.leftSelectAll = false;
      data.leftSelectLength = 0;
      data.rightSelectAll = false
      data.rightSelectLength = 0
      // 进行深拷贝
      if (Array.isArray(props.allData)) {
        data.allDataList = JSON.parse(JSON.stringify(props.allData));
        data.allDataList.sort(sortFun)
      } else {
        data.allDataList = [];
      }
      // 增加限制器 (不可被选中)
      if (props.astrictList.length && data.allDataList.length) {
        data.allDataList.forEach((item: any) => {
          props.astrictList.forEach((ele: any) => {
            if (item[props.showKeyVal.key] === ele[props.showKeyVal.key]) {
              item.disabled = true;
            }
          });
        });
      }
      // 左侧全选是否可选
      let arr = data.allDataList.filter((item: any) => item.disabled);
      if (data.allDataList.length === arr.length) {
        data.whetherCan = true;
      } else {
        data.whetherCan = false;
      }
      // 回归初始位置 (数据切换时执行)
      if (data.leftScrollEle) {
        if (data.leftScrollEle.scrollTop !== 0) {
          data.leftScrollEle.scrollTop = 0;
        }
      }

      // 设置 主单位
      if (props.primaryUnit) data.labelShow = props.primaryUnit

      if (!props.selectDataUpdate) {
        let arr = <any>[];
        props.selectData.forEach((item: any) => {
          if (data.rightDataCopy.indexOf(item[props.showKeyVal.key]) >= 0) {
            arr.push(item);
          }
        });
        bySelectData(arr);
      } else {
        bySelectData(props.selectData);
      }
    }

    // 截取数组 实现分页
    const pagingQuery = (allList: Array<object>, num: number, size: number) => {
      if (!allList.length) {
        return [];
      } else {
        let returnList = [];
        returnList = allList.slice(0, size * num);
        return returnList;
      }
    };

    // 给leftData赋值(是否分页)
    const setLeftData = () => {
      // 是否分页
      let arr = [];
      if (props.whetherPaging) {
        if (data.allDataList.length <= props.showPageSize * data.showPageNum) {
          data.leftData = data.allDataList;
        } else {
          arr = [
            ...pagingQuery(
              data.allDataList,
              data.showPageNum,
              props.showPageSize
            ),
          ];
          // 去重
          data.leftData = [
            ...new Set(arr.map((item) => JSON.stringify(item))),
          ].map((ele) => JSON.parse(ele));
        }
      } else {
        data.leftData = data.allDataList;
      }
    };

    // 被选中参数的方法 (赋值rightData)(父组件传递的值)
    const bySelectData = (list: Array<any>) => {
      if (list.length) {
        if (!props.selectDataUpdate) {
          let assignmentVal = <any>[];
          list.forEach((item: any) => {
            assignmentVal.push(
              ...data.allDataList.filter(
                (ele: { [x: string]: any; }) => ele[props.showKeyVal.key] === item
              )
            );
          });
          let repetition = [...data.rightDataCopy, ...assignmentVal];
          data.rightData = [
            ...new Set(repetition.map((item) => JSON.stringify(item))),
          ].map((ele) => JSON.parse(ele));

          data.rightData.forEach((item: { checkbox: boolean; }) => {
            item.checkbox = false;
          });

          data.rightSelectAll = data.rightData.every((item: { checkbox: any; }) => item.checkbox)

          // 数据删除操作 (从左侧删除)
          for (let i = 0; i < data.rightData.length; i++) {
            for (let j = 0; j < data.allDataList.length; j++) {
              if (
                data.allDataList[j][props.showKeyVal.key] ==
                data.rightData[i][props.showKeyVal.key]
              ) {
                data.allDataList.splice(j, 1);
                if (data.leftSelectLength >= 0) {
                  data.leftSelectLength--;
                }
                data.leftSelectAll = false;
              }
            }
          }
        } else {
          let arr: any[] = [];
          // 进行赋值操作
          for (let i = 0; i < data.allDataList.length; i++) {
            list.forEach((ele) => {
              if (data.allDataList[i][props.showKeyVal.key] == ele) {
                arr.push(data.allDataList[i]);
                data.allDataList[i].checkbox = false;
              }
            });
          }
          data.rightData = [...data.rightData, ...arr];

          data.rightSelectAll = data.rightData.every((item: { checkbox: any; }) => item.checkbox)

          // 数据删除操作 (从左侧删除)
          for (let i = 0; i < list.length; i++) {
            for (let j = 0; j < data.allDataList.length; j++) {
              if (data.allDataList[j][props.showKeyVal.key] == list[i]) {
                data.allDataList.splice(j, 1);
                if (data.leftSelectLength >= 0) {
                  data.leftSelectLength--;
                }
                data.leftSelectAll = false;
              }
            }
          }
        }
        // 在左侧没有值时或者左侧值都不能选中时 禁用全选
        if (data.allDataList.length) {
          if (data.allDataList.length === data.allDataList.filter((item: {disabled: Boolean}) => item.disabled).length) {
            data.whetherCan = true;
          } else {
            data.whetherCan = false;
          }
        } else {
          data.whetherCan = true;
        }
      } else {
        data.rightData = [];
        // 不跟随切换值
        if (!props.selectDataUpdate) {
          data.rightData = [...data.rightDataCopy];
          // 数据删除操作 (从左侧删除)
          for (let i = 0; i < data.rightData.length; i++) {
            for (let j = 0; j < data.allDataList.length; j++) {
              if (
                data.allDataList[j][props.showKeyVal.key] ===
                data.rightData[i][props.showKeyVal.key]
              ) {
                data.allDataList.splice(j, 1);
                if (data.leftSelectLength >= 0) {
                  data.leftSelectLength--;
                }
                data.leftSelectAll = false;
              }
            }
          }
        }
        // 在左侧没有值时或者左侧值都不能选中时 禁用全选
        if (data.allDataList.length) {
          if (
            data.allDataList.length ===
            data.allDataList.filter((item: {disabled: Boolean}) => item.disabled).length
          ) {
            data.whetherCan = true;
          } else {
            data.whetherCan = false;
          }
        } else {
          data.whetherCan = true;
        }
      }

      // 无论data.rightData是否有值 给leftData赋值
      setLeftData();
    };

    // 监听分页(全局)所有数据的监听 (切换数据源)
    watch(
      () => props.allData,
      (val) => {
        refresh()
      },
      { immediate: true, deep: true }
    );

    // 左侧 (全局)
    // 查询事件
    const leftSearch = (text: any) => {
      if (text) {
        let arr: any[] = [];
        data.allDataList.forEach((item: { [x: string]: string | any[]; }) => {
          if (item[props.showKeyVal.label].indexOf(text) >= 0) {
            arr.push(item);
          }
        });
        data.leftData = JSON.parse(JSON.stringify(arr));
        // 搜索项是否已经被全部选中
        let list = data.leftData.filter((item: { disabled: any; }) => !item.disabled)
        if (list.length) {
          data.leftSelectAll = list.every((item: { checkbox: any; }) => item.checkbox)
        } else {
          data.leftSelectAll = false
        }
      } else {
        let arr = data.allDataList.filter((item: { disabled: Boolean}) =>!item.disabled)
        if (data.leftSelectLength !== arr.length) {
          data.leftSelectAll = false
        } else {
          data.leftSelectAll = true
        }
        setLeftData();
      }
    };

    // 单选事件
    const leftRadioSelect = (item: { [x: string]: any; disabled: any; checkbox: boolean; }, notSet: string = '') => {
      // 不可被选中项
      if (item.disabled) return;
      if (notSet === "notSet") {
        if (item.checkbox) {
          data.leftSelectLength++;
        } else {
          data.leftSelectLength--;
        }
      } else {
        // 点击文本的选择
        if (item.checkbox) {
          data.leftSelectLength--;
        } else {
          data.leftSelectLength++;
        }
        item.checkbox = !item.checkbox;
      }
      data.allDataList.forEach((ele: {checkbox: Boolean}) => {
        if (ele[props.showKeyVal.key] === item[props.showKeyVal.key]) {
          ele.checkbox = item.checkbox;
        }
      });
      // 区分搜索和非搜索情况
      if (data.leftSearchText) {
        let arr = data.leftData.filter((item: { disabled: any; }) => !item.disabled)
        data.leftSelectAll = arr.every((item: { checkbox: any; }) => item.checkbox)
      } else {
        let arr = data.allDataList.filter((item: { disabled: Boolean }) => !item.disabled)
        data.leftSelectAll = arr.every((item: {checkbox: Boolean}) => item.checkbox);
      }
    };

    // 左侧内容全选事件
    const leftAllCheckbx = (status: any) => {
      // 全部选中
      if (status) {
        // 在搜索情况下
        if (data.leftSearchText) {
          data.leftData.forEach((item: { [x: string]: any; disabled: any; checkbox: boolean; }) => {
            data.allDataList.forEach((ele: {checkbox: Boolean}) => {
             if (item[props.showKeyVal.key] === ele[props.showKeyVal.key] && !item.disabled) {
              item.checkbox = ele.checkbox = true
              
             }
            })
          })
          data.leftSelectLength = data.allDataList.filter((item: { checkbox: Boolean}) => item.checkbox).length
        // 在非搜索情况下 
        } else {
          data.leftData.forEach((item: { disabled: any; checkbox: boolean; }) => {
             if (!item.disabled && !item.checkbox) {
              item.checkbox = true
            }
          })
          data.allDataList.forEach((ele: {disabled: Boolean, checkbox: Boolean}) => {
            if (!ele.disabled && !ele.checkbox) {
              ele.checkbox = true
            }
          })
          data.leftSelectLength = data.allDataList.filter((item: {disabled: Boolean}) => !item.disabled).length
        }
        
      // 全部取消
      } else {
        if (data.leftSearchText) {
          data.leftData.forEach((item: { [x: string]: any; checkbox: boolean; }) => {
            data.allDataList.forEach((ele: {checkbox: Boolean}) => {
              if (item[props.showKeyVal.key] === ele[props.showKeyVal.key]) {
                item.checkbox = ele.checkbox = false
                data.leftSelectLength--
              }
            })
          })

        // 非搜索取消全选
        } else {
          data.leftData.forEach((item: { disabled: any; checkbox: boolean; }) => {
            if (!item.disabled) {
              item.checkbox = false
            }
          })
          data.allDataList.forEach((ele: {disabled: Boolean, checkbox: Boolean}) => {
            if (!ele.disabled) {
              ele.checkbox = false
            }
          })
          data.leftSelectLength = 0
        }
      }
    };

    // 左侧滚动事件
    const leftScroll = (e: { target: { scrollTop: number; }; }) => {
      if (
        e.target.scrollTop >=
        props.showPageSize * data.showPageNum * 4 * 0.75
      ) {
        data.showPageNum++;
        setLeftData();
      }
    };

    // 按钮事件
    const clickIncident = (val: string) => {
      data.leftSearchText = ''
      data.rightSearchText = ''
      data.rightSearchData = []
      let arr: object[] = [];
      // 退回到leftData 左移事件
      if (val === "back") {
        data.whetherCan = false;
        // 先取出所有没有被选中的元素
        let list = data.rightData.filter((item: { checkbox: any; }) => !item.checkbox);

        // copy 剩余参数
        if (!props.selectDataUpdate) data.rightDataCopy = list;

        data.rightDataCopy.forEach((item: { checkbox: boolean; }) => (item.checkbox = false));

        // 被选中元素量改为0
        data.rightSelectLength = 0;

        // 取消右侧全选
        data.rightSelectAll = false;

        // 遍历 把所有被选中的元素放入左边框
        if (props.allData !== null && props.allData.length) {
          data.rightData.forEach((item: { [x: string]: any; checkbox: boolean; }) => {
            props.allData.forEach((ele: any) => {
              if (item[props.showKeyVal.key] === ele[props.showKeyVal.key]) {
                if (item.checkbox) {
                  // 主单位 被移除 同时
                  if (item[props.showKeyVal.key] === data.labelShow) {
                    data.labelShow = NaN
                  }
                  data.allDataList.push(item);
                  item.checkbox = false;
                }
              }
            });
          });

          data.leftSelectAll = data.allDataList.every((item: {checkbox : Boolean}) => item.checkbox)

        } else {
          data.rightData.forEach((item: { checkbox: boolean; }) => {
            item.checkbox = false;
          });
        }

        // 给右边数组重新赋值
        data.rightData = list;

        // 如果右边还有元素
        if (data.rightData.length) {
          data.rightData.forEach((item: { [x: string]: any; }) => {
            arr.push(item[props.showKeyVal.key]);
          });
        }

        // 给左边元素重新排序
        data.allDataList.sort(sortFun);
        // 选中放入rightData
      } else {
        // 先把右侧的值弹出
        if (data.rightData.length) {
          data.rightData.forEach((ele: { [x: string]: any; }) => {
            arr.push(ele[props.showKeyVal.key]);
          });
        }
        // 再把左侧被选中的值弹出
        data.allDataList.forEach((ele: { [x: string]: object; checkbox: Boolean; }) => {
          if (ele.checkbox === true) {
            arr.push(ele[props.showKeyVal.key]);
            // 保存右侧数据 保留
            if (!props.selectDataUpdate) {
              data.rightDataCopy.push(ele);
            }
          }
        });

        data.rightDataCopy.forEach((item: {checkbox: Boolean}) => (item.checkbox = false));
        // 被选中数据赋值
        bySelectData(arr);

      }

      // 默认给第一个右侧数据添加主【单位】标签
      // 如果有主单位则不调整主单位 否则选择为第一个
      if (!data.labelShow) {
        data.labelShow = data.rightData[0].id
      }

      context.emit('setHost', data.labelShow)

      context.emit("transferChange", arr);
    };

    // 右侧

    // 搜索事件
    const rightSearch = (text: any) => {
      if (text) {
        let arr: any[] = [];
        data.rightData.forEach((item: { [x: string]: string | any[]; }) => {
          if (item[props.showKeyVal.label].indexOf(text) >= 0) {
            arr.push(item);
          }
        });
        data.rightSearchData = JSON.parse(JSON.stringify(arr));
        // 搜索项被选中
        if (data.rightSearchData.length) {
          data.rightSelectAll = data.rightSearchData.every((item: {checkbox: Boolean}) => item.checkbox)
        } else {
          data.rightSelectAll = false
        }
      } else {
        data.rightSearchData = [];
        data.rightSelectAll = data.rightData.every((item: { checkbox: any; }) => item.checkbox)
      }
    };

    // 阻止右侧右击默认事件
    const preventEvent = (e: any) => {
      e.preventDefault();
    }

    // 右侧右击事件
    const rightClick = (e: any, val: {id: number}) => {
      if (e.button == 2) {
        if (data.labelShow === val.id) return
        data.setBtnKey = val.id
      }
    }

    // 设置主单位
    const setHost = () => {
      data.labelShow = data.setBtnKey
      context.emit('setHost', data.labelShow)
    }

    // 右侧全选事件
    const rightAllCheckbx = (status: any) => {
      // 全选为true
      if (status) {
        // 搜索时
        if (data.rightSearchText) {
          data.rightSearchData.forEach((item: {checkbox: Boolean}) => {
            data.rightData.forEach((ele: { [x: string]: any; checkbox: boolean; }) => {
              if (item[props.showKeyVal.key] === ele[props.showKeyVal.key]) {
                ele.checkbox = item.checkbox = true
              }
            })
          })
          data.rightSelectLength = data.rightData.filter((item: { checkbox: any; }) => item.checkbox).length
        // 非搜索时
        } else {
          data.rightData.forEach((item: { checkbox: boolean; }) => {
            item.checkbox = true
          })
          data.rightSelectLength = data.rightData.length
        }
      } else {
        // 搜索时
        if (data.rightSearchText) {
          data.rightSearchData.forEach((item: {checkbox: Boolean}) => {
            data.rightData.forEach((ele: { [x: string]: any; checkbox: boolean; }) => {
              if (item[props.showKeyVal.key] === ele[props.showKeyVal.key]) {
                item.checkbox = ele.checkbox = false
                data.rightSelectLength--
              }
            })
          })
        } else {
          data.rightData.forEach((item: { checkbox: boolean; }) => {
            item.checkbox = false
          })
          data.rightSelectLength = 0
        }
      }
    };

    // 单选事件
    const rightRadioSelect = (item: { [x: string]: any; checkbox: boolean; }, notSet: string = '') => {
      // 无需更改值
      if (notSet === "notSet") {
        if (item.checkbox) {
          data.rightSelectLength++;
        } else {
          data.rightSelectLength--;
        }
      } else {
        // 点击文本
        if (item.checkbox) {
          data.rightSelectLength--;
        } else {
          data.rightSelectLength++;
        }
        item.checkbox = !item.checkbox;
      }
      if (data.rightSearchText) {
        data.rightData.forEach((ele: { [x: string]: any; checkbox: any; }) => {
          if (item[props.showKeyVal.key] === ele[props.showKeyVal.key]) {
            ele.checkbox = item.checkbox
          }
        })
      }
      // 搜索单选 全选按钮的展示
      if (data.rightSearchText) {
        data.rightSelectAll = data.rightSearchData.every((item: {checkbox: Boolean}) => item.checkbox)
      // 非搜索单选
      } else {
        data.rightData.rightSelectAll = data.rightData.every((item: { checkbox: any; }) => item.checkbox)
      }
    };

    return {
      data,
      // left 部分
      leftSearch,
      leftScroll,
      leftAllCheckbx,
      leftRadioSelect,
      // 按钮
      clickIncident,
      // right 部分
      setHost,
      rightSearch,
      preventEvent,
      rightClick,
      rightAllCheckbx,
      rightRadioSelect,
    };
  },
};
</script>

以上 实现的功能有 穿梭(基础功能) 右侧右击添加单位(业务需求)数据截取分页功能(毫无必要的需求,我都不知道我又没有写完🤷‍♂️)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值