vue3左树的全选和反选

 <el-input v-model="filterText" placeholder="" style="width: 48%"/>
                  <el-button type="primary" @click="handleSearch" class="ml-2">查找</el-button>
                  <el-radio-group v-model="form.choice" @change="handleCheckAll">
                    <el-radio label="all" class="ml-2">全选</el-radio>
                    <el-radio label="invert">反选</el-radio>
                  </el-radio-group>
                  <el-tree
                    ref="treeRef"
                    class="filter-tree"
                    :data="treeData"
                    :props="defaultProps"
                    show-checkbox
                    node-key="id"
                    :filter-node-method="filterNode"
                  >
                    <template #default="{ node, data }">
                      <div style="display: flex;">
                        <span style="margin-right: 8px">{{ node.label }}</span>
                        <span>
<!--            <a @click="append(data)"> Append </a>-->
                          <!--            <el-link  @click="remove(node, data)"><el-icon><Delete /></el-icon></el-link>-->
          </span>
                        <!--          <IconifyIconOffline :icon="Del" class="relink-btn-icon" />-->
                      </div>
                    </template>
                  </el-tree>

const filterText = ref("");

const treeRef = ref<InstanceType<typeof ElTree>>();
interface Tree {
  id: number
  label: string
  children?: Tree[]
  checked?: boolean;
}

const defaultProps = {
  children: "children",
  label: "label"
};
const filterNode = (value: string, treeData: Tree) => {
  if (!value) return true;
  return treeData.label.includes(value);
};
const handleSearch = () => {
  treeRef.value!.filter(filterText.value);
}
const getAllNodeKeys = (nodes: Tree[], keys: number[] = []) => {
  nodes.forEach((node) => {
    keys.push(node.id);
    if (node.children) {
      getAllNodeKeys(node.children, keys);
    }
  });
  return keys;
};
const handleCheckAll = (value: string) => {
  if (value === 'all') {
   // for (let i = 0; i < treeData.value.length; i++) {
     // if (treeRef.value.getNode(treeData.value[i]).disabled == false) {
      //  treeRef.value.setChecked(treeData.value[i].id, true, true);
      //}
    //}
    const allKeys = getAllNodeKeys(treeData.value);
    treeRef.value!.setCheckedKeys(allKeys, false)
  } else {
    //treeRef.value.setCheckedKeys([])

    const allKeys = getAllNodeKeys(treeData.value);// 获取所有节点的 key
    const checkedKeys = treeRef.value?.getCheckedKeys() || [];// 获取当前选中的节点
    const newCheckedKeys = allKeys.filter((key) => !checkedKeys.includes(key)); // 新的选中节点为未选中的节点
    treeRef.value!.setCheckedKeys(newCheckedKeys)
  }
}

<template>
  <div class="main">
    <!--    添加树-->
    <div style="width: 100%;margin: 10px">

      <AddLink @click="handleBtnClick" style="margin-right: 10px" />
      <div v-if="showInput">
        <el-input v-model="content" style="width: 30%" />
        <el-button @click="handleClick">确定</el-button>
      </div>
      <el-input v-model="filterText" placeholder="Filter keyword" style="width: 50%" />
      <el-tree
        ref="treeRef"
        class="filter-tree"
        :data="treeData"
        :props="defaultProps"
        show-checkbox
        :filter-node-method="filterNode"
      >
        <template #default="{ node, data }">
          <div style="display: flex;">
            <span style="margin-right: 8px">{{ node.label }}</span>
            <span>
<!--            <a @click="append(data)"> Append </a>-->
              <!--            <el-link  @click="remove(node, data)"><el-icon><Delete /></el-icon></el-link>-->
          </span>
            <!--          <IconifyIconOffline :icon="Del" class="relink-btn-icon" />-->
          </div>
        </template>
      </el-tree>
    </div>
  </div>
</template>
<script setup lang="ts">
import { useI18n } from "vue-i18n";
import { reactive, ref, onMounted, computed, watch, nextTick } from "vue";
import { ElTree } from "element-plus";
import Del from "@iconify-icons/mdi/delete-forever-outline";
import { Delete } from '@element-plus/icons-vue'
defineOptions({
  name: "tree"
});

interface Tree {
  id: number
  label: string
  children?: Tree[]
}

const defaultProps = {
  children: "children",
  label: "label"
};
const filterText = ref("");
const content = ref("");
const showInput = ref(false);
const treeRef = ref<InstanceType<typeof ElTree>>();
const filterNode = (value: string, treeData: Tree) => {
  if (!value) return true;
  return treeData.label.includes(value);
};
const treeData= ref(
  [
    {
      id: 1,
      label: "维护文档",
      children: [
        {
          id: 4,
          label: "拓扑图"
        },
        {
          id: 5,
          label: "端口表"
        },
        {
          id: 6,
          label: "配置信息"
        }
      ]
    },
    {
      id: 2,
      label: "制度规范"
    },
    {
      id: 3,
      label: "工程资料",
      children: [
        {
          id: 7,
          label: "xxx工程资料1"
        },
        {
          id: 8,
          label: "xxx工程资料2"
        }
      ]
    }
  ]
)
const handleBtnClick = () => {
  showInput.value = true;
};
const handleClick = () => {
  if (content.value) {
    treeData.value.push({
      label: content.value,
    });
    content.value = ''; // 清空输入框
  }
  // const newChild ={ id: 12, lable: content.value, children: [] };
  // treeData.push(newChild)
  // treeData.value = [...treeData.value]
  // console.log( content.value, "-------------content.value------");
  // console.log(treeData.value,'---treeData--');
}

onMounted(async () => {

});

watch(filterText, (val) => {
  treeRef.value!.filter(val);
});
watch(treeData, (val) => {
  if(val){
    console.log(treeData,'---treeData--');
  }
});

</script>

<style lang="scss" scoped>
@import "@/style/component.scss";
</style>

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值