vue2自定义-多选下拉框

这是一个多选下拉框的组件,简单弄了一个样式,后续有时间可以会加一下动画效果啥的,现在将就着用先。

通过父组件传入数据可以实现多数据多页面的复用。


子组件:
html部分:

<template>
  <div class="select_wrap">
    <div class="content" @click.stop="togglePanel">
      <div class="selected_item">
        <div>{{ defaultValue }}</div>
      </div>
    </div>
    <div v-if="panelShow" class="checkbox_content">
      <div class="checkbox_list">
        <div :class="['select_item', { 'select_item_active': isAll }]" @click.stop="handleAll">全部</div>
        <div v-for="item in courseData" :key="item.id" :class="['select_item', { 'select_item_active': item.checkType }]" @click.stop="toggleItem(item)">
          <input type="checkbox" v-model="item.checkType">
          <span>{{ item.text }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

js部分:

<script>
export default {
  name: "Select",
  props: {
    courseData: {
      type: Array,
      required: true,
      default:{}
    }
  },
  data() {
    return {
      selectData: [],
      panelShow: false,
      isAll: false
    };
  },
  computed: {
    defaultValue() {
      if (this.isAll) {
        return '全部';
      } else if (this.selectData.length > 0) {
        return this.selectData.map(item => item.text).join(', ');
      } else {
        return this.courseData.length ? this.courseData[0].text : null;
      }
    }
  },
  watch: {
    courseData: {
      immediate: true,
      handler() {
        this.resetSelections();
      }
    }
  },
  methods: {
    togglePanel() {
      this.panelShow = !this.panelShow;
      if (this.panelShow) {
        document.addEventListener("click", this.closeList);
      } else {
        document.removeEventListener("click", this.closeList);
        this.validateSelections();
      }
    },
    toggleItem(item) {
      item.checkType = !item.checkType;
      this.updateSelections();
    },
    handleAll() {
      this.isAll = !this.isAll;
      if (this.isAll) {
        this.courseData.forEach(item => {
          item.checkType = true;
        });
        this.selectData = [...this.courseData];
      } else {
        this.courseData.forEach(item => {
          item.checkType = false;
        });
        this.selectData = [];
      }
      this.$emit("change", this.selectData);
    },
    updateSelections() {
      this.selectData = this.courseData.filter(item => item.checkType);
      this.isAll = this.selectData.length === this.courseData.length;
      this.$emit("change", this.selectData);
    },
    validateSelections() {
      if (!this.selectData.length) {
        this.courseData[0].checkType = true;
        this.selectData = [this.courseData[0]];
        this.isAll = false;
      }
    },
    resetSelections() {
      this.selectData = this.courseData.filter(item => item.checkType);
      this.isAll = this.selectData.length === this.courseData.length;
    },
    closeList() {
      this.panelShow = false;
    }
  }
};
</script>

css部分:


<style lang="scss" scoped>
/* 多选显示区 */
.select_wrap {
  position: relative;
  width: 120px;
  .content {
    display: flex;
    align-items: center;
    border-radius: 2px;
    border: 1px solid rgba(0, 0, 0, 0.3);

    .selected_item {
      display: flex;
      align-items: center;
      border-radius: 2px;
      padding: 0 10px;
    }
  }
  .checkbox_content {
    position: absolute;
    left: 0;
    top: 30px;
    width: 100%;
    .checkbox_list {
      position: absolute;
      border: 1px solid rgba(0, 0, 0, 0.3);
      left: 0;
      top: 0;
      right: 0;
      height: 100px;
      background-color: #fff;
      padding: 10px 0;
      z-index: 99;
      text-align: left;
      overflow: hidden;
      overflow-y: auto;

      /* 滚动条样式 */
      &::-webkit-scrollbar {
        width: 6px; /*  设置纵轴(y轴)轴滚动条 */
        height: 6px; /*  设置横轴(x轴)轴滚动条 */
      }
      /* 滚动条滑块(里面小方块) */
      &::-webkit-scrollbar-thumb {
        border-radius: 10px;
        background: #fff;
      }
      /* 滚动条轨道 */
      &::-webkit-scrollbar-track {
        border-radius: 0;
        box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
        background: transparent;
      }

      .select_item {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 25px;
        padding: 0 5px;
        cursor: pointer;
        &:hover {
          background: orange;
        }
      }

      .select_item_active {
        background: orange;
      }

      input {
        height: 16px;
        width: 16px;
        border: 1px solid rgba(0, 0, 0, 0.3);
      }
    }
  }
}

</style>

父组件就直接来了

<template>
  <div class="home">
    <HelloWorld :courseData="courseData" />
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'HomeView',
  components: {
    HelloWorld
  },
  data() {
    return {
      courseData: [
        { id: "1", text: "理想", checkType: true },
        { id: "2", text: "蔚来", checkType: false },
        { id: "3", text: "小米", checkType: false },
      ],
    }
  }
}
</script>
<style>

.home{
  padding: 50px;
}
</style>

感兴趣的可以直接跑一下。 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 ant-design-vue 中,下拉框多选自定义选项可以通过 `template` 和 `render` 方法来实现。 使用 `template` 的方式,可以在 `<a-select-option>` 标签内编写自定义的选项内容。例如: ```html <a-select v-model="selectedOptions" mode="multiple"> <a-select-option v-for="option in options" :key="option.value"> <span>{{ option.label }}</span> <a-checkbox v-model="option.checked"></a-checkbox> </a-select-option> </a-select> ``` 在上面的代码中,`options` 是一个数组,用于存储所有的选项。每个选项包含 `label` 和 `value` 属性,以及一个 `checked` 属性用于记录是否选中。通过循环遍历 `options` 数组,使用 `<a-select-option>` 标签来创建每个选项,并在其中放置自定义的内容。 使用 `render` 方法的方式更加灵活,可以直接通过 JavaScript 代码来生成自定义选项。例如: ```html <a-select v-model="selectedOptions" mode="multiple"> <template v-for="option in options"> <a-select-option :value="option.value" :key="option.value"> {{ option.label }} <a-checkbox v-model="option.checked"></a-checkbox> </a-select-option> </template> </a-select> ``` 在上面的代码中,通过 `<template>` 标签来生成多个 `<a-select-option>` 标签,然后在其中使用 JavaScript 代码来设置 `value` 和 `key` 属性,并添加自定义内容。 需要注意的是,无论使用 `template` 还是 `render` 方法,都需要使用 `v-model` 来绑定选中的选项,以及在选项中设置 `value` 属性和 `key` 属性。另外,还可以根据具体需求在选项中添加其他自定义的组件或标签。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值