vue2实现一个上边为搜索,下面为复选框选中后,右侧显示已选中组件

目录

  • vue2实现一个上边为搜索,下面为复选框选中后,右侧显示已选中组件
    • component / ProjectSelectItem.vue
    • 使用组件
    • 效果

vue2实现一个上边为搜索,下面为复选框选中后,右侧显示已选中组件

component / ProjectSelectItem.vue

<template>
    <div class="project-wrap">
      <!-- selectObj {{ selectObj }} -->
      <div class="project-wrap-top">
        <el-input placeholder="请输入内容" v-model="searchVal" @input="searchChange" clearable style="width:300px">
          <i slot="prefix" class="el-input__icon el-icon-search"></i>
        </el-input>
      </div>
      <div class="project-wrap-con">
        <div class="project-wrap-left" v-loading="loading">
          <template v-if="serachData&&serachData.length > 0">
            <div class="project-wrap-left-item" v-for="(item,idx) in serachData" :key="idx">
            <div class="item-left">
              <i class="el-input__icon item-left-icon el-icon-folder-opened"></i>
              <span> {{ item.label }} </span>
            </div>
            <div class="item-right">
              <el-checkbox v-model="item.checkedVal" @change="checkedChange(item)"></el-checkbox>
            </div>
          </div>
          </template>
          <div v-else>
            <div v-show="!loading">暂无数据</div>
          </div>
        </div>
        <div class="project-wrap-right">
          <div class="project-wrap-right-top">
            已选项目
          </div>
          <div class="project-wrap-right-con" v-if="selectObj.code">
            <i class="el-input__icon item-left-icon el-icon-folder-opened"></i>
            <span> {{ selectObj.label }} </span>
          </div>
        </div>
      </div>
    </div>
</template>

<script>
export default {
  name: "ProjectSelectItem",
  props:{
    // 列表数据
    projectData:{
      type: Array,
      default:()=>{
        return []
      }
    },
    // 选中的数据
    selectPropsObj:{
      type: Object,
      default:()=>{
        return {
          code:'',
          label:'',
          checkedVal:false
        }
      } 
    },
    loading:{
      type: Boolean,
      default:false
    },
  },
  components: {},
  data() {
    return {
      searchVal: "", // 搜索的值
      selectObj:{
        code:'',
        label:'',
        checkedVal:false
      },
      // 初始化完整的数据
      projectAllData:[],
      // 查询后的数据
      serachData:[],
      timer:null
    };
  },
  watch:{
    projectData: {
      handler: function() {
        this.init();
      },
      deep:true,
      immediate:true
    } 
  },
  created() {
    this.init()
  },
  destroyed(){
    clearInterval(this.timer);
  },
  methods: {
    init(){
      // 请求数据
      this.projectAllData = [...this.projectData]
      this.serachData = [...this.projectData]
      // 已经有选中的时候 回显效果
      this.selectObj = {...this.selectPropsObj };
      if ( this.selectObj.checkedVal ) {
        this.serachData = this.serachData ? this.serachData.map(item=>{
          if(item.code === this.selectObj.code ) {
              item.checkedVal = true;
            } else {
              item.checkedVal = false
            }
            return item
        }) : []
      }
    },
    // 勾选
    checkedChange(val){
      console.log('checkedChange', val);
      // 01:没有搜索值 // 02:有搜索值
      if ( !this.searchVal ) {
        this.projectAllData = this.projectAllData ? this.projectAllData.map(item=>{
          if(item.code === val.code) {
            item.checkedVal = val.checkedVal;
          } else {
            item.checkedVal = false
          }
          return item
        }) : []
        this.selectObj.code = val.checkedVal ? val.code : '';
        this.selectObj.label = val.checkedVal ? val.label : '';
        this.selectObj.checkedVal = val.checkedVal ? val.checkedVal : false;
      } else {
        this.serachData = this.serachData ? this.serachData.map(item=>{
          if(item.code === val.code) {
            item.checkedVal = val.checkedVal;
          } else {
            item.checkedVal = false
          }
          return item
        }) : []
        this.selectObj.code = val.checkedVal ? val.code : '';
        this.selectObj.label = val.checkedVal ? val.label : '';
        this.selectObj.checkedVal = val.checkedVal ? val.checkedVal : false;
      }
      this.$emit('getSelectObj',this.selectObj)
    },
    // 搜索
    searchChange() {
      clearInterval(this.timer);
      this.timer = setTimeout(()=> {
        this.serachData = this.createFilter(this.searchVal)
        // console.log('this.serachData',this.serachData);
        // console.log('this.selectObj',this.selectObj);
        this.serachData = this.serachData ? this.serachData.map(item=>{
          if(item.code === this.selectObj.code ) {
            item.checkedVal = true;
          } else {
            item.checkedVal = false
          }
          return item
        }) : []
      }, 300);
    },
    // 过滤
    createFilter(queryString) {
      // console.log('queryString',queryString);
      queryString = queryString ? queryString.trim() : ''
      let result = []
      result = this.searchVal ? 
      this.projectAllData.filter(item => {
        return (
          item.label.toLowerCase().indexOf(queryString.toLowerCase()) === 0 || 
          item.code.toLowerCase().indexOf(queryString.toLowerCase()) === 0
        )
      })
       : this.projectAllData
      return result
    },
  },
}
</script>

<style  lang="scss" scoped>
.project-wrap {
  background: #eee;
  width: 600px;
  height: 100%;
  .project-wrap-top {
    margin-left: 20px;
    height: 80px;
    line-height: 80px;
    border-bottom: 2px solid #000;
    text-align: left;
  }
  .project-wrap-con {
    display: flex;
    // height: 100%;
    height: calc(100% - 80px);
    overflow: auto;
    .project-wrap-left {
      width: 400px;
      overflow: auto;
      border-right: 2px solid #000;
      padding: 10px 20px;
      .project-wrap-left-item {
        display: flex;
        justify-content: space-between;
        height: 34px;
        line-height: 34px;
        width: 100%;
        // background: yellow;
        overflow: hidden;
        .item-left {
          display: flex;
          width: 330px;
          // background: #ddd;
          .item-left-icon {
            line-height: 24px;
          }
        }
        .item-right {
          width: 30px;
          // background: #eee;
        }
      }
    }
    .project-wrap-right {
      width: 160px;
      overflow: auto;
      padding: 10px;
      text-align: left;
      .project-wrap-right-top {
        font-size: 18px;
        color: #ccc;
        margin-bottom: 10px;
      }
      .project-wrap-right-con {
        padding: 2px;
        background: #cdcdcd;
        min-height: 34px;
      }
    }
  }
}
</style>

使用组件

     selectObj {{ selectObj }}
    <ProjectSelectItem :projectData="testData" @getSelectObj="getSelectObj" :selectPropsObj="selectObj" :loading="loading" />
    selectObj1 {{ selectObj1 }}
    <ProjectSelectItem :projectData="testData1" @getSelectObj="getSelectObj1"  />
    selectObj2 {{ selectObj2 }}
    <ProjectSelectItem :projectData="testData2"  @getSelectObj="getSelectObj2"  />
    <div></div>

  data() {
    return {
      selectObj:{
        code:'1',
        label:'深圳市XX运信息咨询有限公司1',
        checkedVal:true,
      },
      loading:false,
      selectObj1:{
        code:'',
        label:'',
        checkedVal:false
      },
      selectObj2:{
        code:'',
        label:'',
        checkedVal:false
      },
      // 使用扁平化数据
      testData:[],
      testData1:[
        {
          code:'01',
          label:'深圳市XX运信息咨询有限公司01',
          checkedVal:false,
        },
        {
          code:'02',
          label:'运营二部02',
          checkedVal:false,
        },
        {
          code:'03',
          label:'运营二部03运营二部运营二部运营二部运营二部运营二部运营二部',
          checkedVal:false,
        },
        {
          code:'04',
          label:'人事服务04',
          checkedVal:false,
        },
        {
          code:'010',
          label:'深圳市XX运信息咨询有限公司010',
          checkedVal:false,
        },
      ],
      testData2:[
        {
          code:'001',
          label:'公司001',
          checkedVal:false,
        },
        {
          code:'002',
          label:'运营三部002',
          checkedVal:false,
        },
        {
          code:'003',
          label:'运营三部003运营三部运营三部',
          checkedVal:false,
        },
        {
          code:'004',
          label:'人事服务004',
          checkedVal:false,
        },
        {
          code:'0010',
          label:'深圳市XX运信息咨询有限公司0010',
          checkedVal:false,
        },
      ]
    };
  },

  created() {
    // 初始化数据
    let initData = [
      {
        code:'1',
        label:'深圳市XX运信息咨询有限公司1',
        children:[
          {
            code:'1-0',
            label:'深圳市XX运信息咨询有限公司1-0',
          }
        ]
      },
      {
          code:'2',
          label:'运营二部2',
          children:[
            {
              code:'2-0',
              label:'深圳市XX运信息咨询有限公司2-0',
            }
          ]
        },
        {
          code:'3',
          label:'运营二部3运营二部运营二部运营二部运营二部运营二部运营二部',
          children:null
        },
        {
          code:'4',
          label:'人事服务4',
          children:[
            {
              code:'4-0',
              label:'人事服务4-0',
              children:[
                {
                  code:'4-0-0',
                  label:'人事服务4-0-0',
                },
              ]
            },
            {
              code:'4-1',
              label:'人事服务4-1',
            }
          ]
        }
    ]
    initData = this.treeToOneArr(initData);
    initData = initData ? initData.map(item=>{
      this.$set(item,'checkedVal',false);
      return item
    }):[];
    this.loading = true;
    setTimeout(()=>{
      this.testData = [...initData]
      this.loading = false;
      console.log('父组件-initData',initData,'this.testData',this.testData);
    },1000)

    // console.log('父组件-initData',initData,'this.testData',this.testData);
  },
  methods: {
    // 获取到数据
    getSelectObj(val){
      this.selectObj = {...val}
    },
    getSelectObj1(val){
      this.selectObj1 = {...val}
    },
    getSelectObj2(val){
      this.selectObj2 = {...val}
    },
    treeToOneArr(arr) {
      const data = JSON.parse(JSON.stringify(arr)) // 对传入的参数进行深拷贝
      const newData = [] // 创建空数组用来接收操作后的新数组
      const hasChildren = item => {
        // 递归遍历,把包含children的选项拿出来,push到之前新建的空数组内
        (item.children || (item.children = [])).map(v => {
          hasChildren(v)
        })
        delete item.children // 删除原children属性,可选项
        newData.push(item)
      }
      data.map(v => hasChildren(v))
      return newData
    },
  },

效果

vue2实现一个上边为搜索,下面为复选框选中后,右侧显示已选中组件_第1张图片

你可能感兴趣的:(vue组件,前端,javascript,vue.js)