图片实现复选/单选框效果

747 阅读2分钟

最近在做项目时遇到一个需求,类似于:

image.png 也就是以图片的形式来代替传统的复选框,从而实现想要的效果

由于项目中用到的框架是 elemenu-ui,因此当时的第一反应就是基于element-ui的单选框和复选框进行拓展,但是一番尝试之后发现效果并不好 因此最后决定用原生input框去进行实现

最终实现的代码如下:

imgChecked.vue

<template>
  <div class="home-app">
    <div class="image-container">
      <label class="custom-checkbox" v-for="(item, index) in displayedIcons" :key="index">
        <!-- 复选框 -->
        <input type="checkbox" />
        <img :src="item.imgurl" class="img" alt="Checkbox Image" @click="currentBankClickHandle(item)" />


        <!-- 单选框 -->
        <!-- <input type="radio" name="image" v-model="selectedImage" :value="item" />
        <img :src="item.imgurl" class="img" alt="Radio Image" @click="currentBankClickHandle(item)" /> -->
      </label>
      <div class="tools">
        <el-button v-if="!showAll && iconsList.length > itemsPerRow" @click="showAll = true" type="text">
          <span style="padding-right: 8px">...</span>加载更多</el-button>
        <el-button type="text" icon="el-icon-top" v-else-if="showAll && iconsList.length > itemsPerRow"
          @click="showAll = false">收起</el-button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    itemsPerRow: {
      type: Number,
      default: 8,
    },
    iconsList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      checkboximg: require("@/assets/logo.png"),
      showAll: false,

      // 针对单选框
      // selectedImage: null,
    };
  },
  // 计算属性用于根据showAll状态过滤要显示的图片
  computed: {
    displayedIcons() {
      if (this.showAll) {
        return this.iconsList;
      } else {
        // 只显示前itemsPerRow个项目
        return this.iconsList.slice(0, this.itemsPerRow);
      }
    },
  },
  methods: {
    currentBankClickHandle(item) {
      // 复选框
      // 切换选中状态
      item.checked = !item.checked;
      // 打印名称,如果需要的话
      if (item.checked) {
        this.$emit("changeValueClick", item.name);
      }

      // 单选框
      // if (this.selectedImage !== item) {
      //   this.selectedImage = item;
      //   this.$emit("changeValueClick", item.name);
      // } else {
      //   this.selectedImage = null;
      //   console.log(this.selectedImage);
      // }
    },
  },
};
</script>

<style lang="scss" scoped>
/* 覆写 elementui 样式 */
::v-deep .tools .el-button {
  font-weight: normal;
  font-size: 14px !important;
}

.image-container {
  width: 1200px;
  height: 37px;
  margin: 0 auto;
  box-sizing: border-box;
  position: relative;
}

.tools {
  position: absolute;
  right: 20px;
  top: 0px;
  font-size: 14px;
}

/* 隐藏原生的复选框 */
.custom-checkbox input[type="radio"] {
  display: none;
}

/* 定义自定义复选框的样式 */
.custom-checkbox {
  display: inline-block;
  position: relative;
  cursor: pointer;
  padding-left: 25px;
  width: 120px;
  height: 37px;
  margin-bottom: 12px;
  border-radius: 0;
  vertical-align: top;
  box-sizing: border-box;
}

/* 创建复选框的图片样式 */
.custom-checkbox img {
  position: absolute;
  top: 0;
  left: 0;
  width: 120px;
  height: 37px;
  border: 1px solid #ccc;
}

/* 定义单选框选中状态的样式 */
/* .custom-checkbox input[type="radio"]:checked+img {
  border-color: #448ef7;
  border-bottom: 6px solid #448ef7;
  transform: scale(1.02);
} */

/* 定义复选框选中状态的样式 */
.custom-checkbox input[type="checkbox"]:checked+img {
  border-color: #448ef7;
  border-bottom: 6px solid #448ef7;
  transform: scale(1.02);
}

/* 鼠标移动上去时的样式 */
.custom-checkbox img:hover {
  border-color: #448ef7;
}

/* 图片容器 */
.image-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 16px;
}

/* 加载更多和收起按钮 */
button {
  background-color: transparent;
  border: none;
  cursor: pointer;
  font-size: 16px;
  color: #007bff;
}
</style>

home.vue

<template>
  <div class="home-app">
    <imgChecked
      :iconsList="iconsList"
      :itemsPerRow="8"
      @changeValueClick="changeValueClick"
    />
  </div>
</template>

<script>
import imgChecked from "@/components/imgChecked.vue";

export default {
  components: {
    imgChecked,
  },
  data() {
    return {
      checkboximg: require("@/assets/logo.png"),
      iconsList: [
        {
          imgurl: require("@/assets/logo.png"),
          name: "建设银行",
          id: 1,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "邮政银行",
          id: 2,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "上海浦发银行",
          id: 3,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "富滇银行",
          id: 4,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "中国农业银行",
          id: 5,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "中国银行",
          id: 6,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "重庆银行",
          id: 7,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "华夏银行",
          id: 8,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "渤海银行",
          id: 9,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "交通银行",
          id: 10,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "光大银行",
          id: 11,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "中国工商银行",
          id: 12,
        },
        {
          imgurl: require("@/assets/logo.png"),
          name: "招商银行",
          id: 13,
        },
      ],
    };
  },
  methods: {
    changeValueClick(val) {
      console.log(val);
    },
  },
};
</script>

最终效果图:

image.png

image.png

image.png

用到项目中:

image.png