如何实现el-select多选下拉框中嵌套复选框并加校验不为空功能呢?

如何实现el-select多选下拉框中嵌套复选框并加校验不为空功能呢?

要实现的效果图

选择部分品牌但不选选项效果

问题概述

相信大家看到上面的两张图片后,在脑子里多少会有一些实现思路,这是我最近在开发中遇到的一个小功能,本来看起来挺简单的,愣是控了我两个小时。立马有了一个记录下来的想法,以保证以后遇到一样的问题不被控。

下面我来说一下,我在做这个功能时遇到的一些问题。

第一个问题,el-select组件如何跟el-checkbox组件无缝衔接呢?

第二个问题,如何给这个form表单加校验呢?

实现方案

  1. 通过自定义下拉框内容嵌套复选框组件
  2. 通过@click.stop阻止下拉框中的原来的点击事件
  3. 通过自定义校验规则实现选择部分品牌时,下拉框不能为空功能

el-select组件与el-checkbox组件无缝衔接

实现代码如下:

javascript 复制代码
<el-radio-group style="margin-bottom: 10px" v-model="radio">
  <el-radio label="all">全部品牌</el-radio>
  <el-radio label="part">部分品牌</el-radio>
</el-radio-group>
<el-select
  v-if="radio === 'part'"
  v-model="brandList"
  multiple
  placeholder="请选择品牌"
>
  <el-checkbox-group
    v-model="brandList"
    @change="handleBrandChecked"
  >
    <el-option
      v-for="item in brandOptions"
      :key="item.value"
      :label="item.label"
      :value="item.value"
    >
      <div @click.stop>
        <el-checkbox :label="item.value">{{ item.label }}</el-checkbox>
      </div>
    </el-option>
  </el-checkbox-group>
</el-select>

温馨提示:一定要记得在data和methods中定义所需要的数据和方法哦

代码如下:

javascript 复制代码
<script>
  export default {
    data() {
      return {
      	// 单选框绑定值
        radio: '',
        // 品牌绑定值
        brandList: [],
        // 品牌选项
        brandOptions: [
		    {
		      value: "option1",
		      label: "选项1",
		    },
		    {
		      value: "option2",
		      label: "选项2",
		    },
		    {
		      value: "option3",
		      label: "选项3",
		    },
		  ],
      };
    },
    methods: {
      handleBrandChecked(val) {
        console.log(val);
      }
    }
  }
</script>

给form表单加自定义校验规则

最终代码如下:

javascript 复制代码
<el-form label-position="top" :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px">
  <el-form-item label="授权品牌" prop="licensingBrand">
    <el-radio-group style="margin-bottom: 10px" v-model="ruleForm.licensingBrand">
	 <el-radio label="all">全部品牌</el-radio>
	  <el-radio label="part">部分品牌</el-radio>
	</el-radio-group>
	<el-select v-if="ruleForm.licensingBrand === 'part'" v-model="brandList" multiple placeholder="请选择品牌">
	  <el-checkbox-group v-model="brandList" @change="handleBrandChecked">
	    <el-option v-for="item in brandOptions" :key="item.value" :label="item.label" :value="item.value">
	      <div @click.stop>
	        <el-checkbox :label="item.value">{{ item.label }}</el-checkbox>
	      </div>
	    </el-option>
	  </el-checkbox-group>
	</el-select>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
    <el-button @click="resetForm('ruleForm')">重置</el-button>
  </el-form-item>
</el-form>
<script>
  export default {
    data() {
      var checkLicensingBrand = (rule, value, callback) => {
        if(value === 'part'){
	      if(this.brandList.length === 0){
	        callback(new Error("请选择授权品牌"));
	      }else{
	        callback();
	      }
	    }else{
	      callback();
	    }
      };
      return {
        ruleForm: {
          licensingBrand: '',
        },
        rules: {
          licensingBrand: [
          	{ required: true, message: "请选中授权品牌", trigger: ["blur", "change"] },
            { validator: checkLicensingBrand, trigger: 'change' }
          ],
        },
        // 品牌绑定值
        brandList: [],
        // 品牌选项
        brandOptions: [
		    {
		      value: "option1",
		      label: "选项1",
		    },
		    {
		      value: "option2",
		      label: "选项2",
		    },
		    {
		      value: "option3",
		      label: "选项3",
		    },
		  ],
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
      	this.brandList = [];
        this.$refs[formName].resetFields();
      }
    }
  }
</script>

到此,想要的效果就实现了。

有需要的朋友,拿走不谢

咱们下次再见。

相关推荐
ikoala12 小时前
DeepSeek 官方仓库惊现 DeepSeek Harness 桌面端!
前端·javascript·后端
liangshanbo121513 小时前
React useEffect 与 useLayoutEffect 面试题整理
前端·javascript·react.js
Bs_MoneyMagnet13 小时前
基于springboot+vue的旅游景区点评系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·旅游
ID346107442013 小时前
【课程设计】基于Spring Boot+Vue的校园共享无人机服务系统设计与实现-计算机毕设 附源码44219
javascript·vue.js·spring boot·python·node.js·php·课程设计
夜不会漫长13 小时前
C++:类和对象(2)
java·javascript·c++
掰头战士13 小时前
聊聊 Function Calling,你的模型是否答非所问?
前端·typescript·agent
Yeyu13 小时前
车载多 App 同屏渲染(三):RemoteCompose 序列化 UI
前端
weixin1997010801614 小时前
[特殊字符]《京东POP二手品类对接:B2C订单模型 vs 二手C2C属性的字段转换难题》(附Python源码)
前端·python·算法
BillKu14 小时前
Vue3 可拖拽分栏布局:两种实现方式详解
javascript·vue.js·ecmascript
三小河15 小时前
AI 对话 "打字机" 是怎么实现的?从 SSE 流式、Markdown 组件到 Nginx 防粘连
前端·人工智能·面试