<el-select> 在下拉选项框中添加一个按钮,实现子选项的添加

该文章展示了如何在Vue.js应用中使用el-select组件,监听visible-change事件来动态添加元素,并通过传递方法到子组件来控制弹窗的显示和关闭。同时,文章还涉及到自定义元素样式和事件绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

父组件

 

<el-select
                    v-model="value"
                    placeholder="请选择"
                    ref="add"
                    @visible-change="
                      (v) =>
                        visibleChange(
                          v,
                          'add',
                          //() => {
                           // categoriesClick(temp);//需要传递参数
                         // },
                         categoriesClick,//无需参数
                          '添加设备'
                        )
                    "
                  >
                    <el-option
                      v-for="itemin options"
                      :key="item.value"
      				  :label="item.label"
    			 	  :value="item.value"
                    />
                  </el-select>


<el-dialog
        title="添加子选项"
        :visible.sync="openOff"
        width="70%"
        append-to-body
      >
        <childrenVue 
          @closeHandle="closeHandle"
        />
      </el-dialog>

<script>
import childrenVue from "子组件路径";
  export default {
  components: { childrenVue  },
    data() {
      return {
        openOff:false,
        options: [{
          value: '选项1',
          label: '黄金糕'
        }, {
          value: '选项2',
          label: '双皮奶'
        }, {
          value: '选项3',
          label: '蚵仔煎'
        }, {
          value: '选项4',
          label: '龙须面'
        }, {
          value: '选项5',
          label: '北京烤鸭'
        }],
        value: ''
      }
    }
    methods:{
// 关闭弹窗(传递给子组件处理弹窗关闭)
    closeHandle() {
      this.openOff = false;
    },
    // 弹出添加子选项弹窗(value未传递的参数)
    categoriesClick(value) {   
      this.openOff = true;
    },
    // 在下拉框处显示添加按钮
    visibleChange(visible, refName, onClick, addname) {
      if (visible) {
        const ref = this.$refs[refName];
        let popper = ref[0].$refs.popper;
        if (popper.$el) popper = popper.$el;
        if (
          !Array.from(popper.children).some(
            (v) => v.className === "el-cascader-menu__list"
          )
        ) {
          const el = document.createElement("ul");
          el.className = "el-cascader-menu__list";
          el.style =
            "border-top: solid 1px #E4E7ED; padding:0; color: #606266;";
          el.innerHTML =
            `<li class="el-cascader-node text-center" style="height:50px;line-height: 50px">
                <span class="el-cascader-node__label"><i class="font-blue el-icon-plus"></i>` +
            addname +
            `</span>
                </li>`;
          popper.appendChild(el);
          el.onclick = () => {
            // 底部按钮的点击事件 点击后想触发的逻辑也可以直接写在这
            onClick && onClick();

            // 以下代码实现点击后弹层隐藏 不需要可以删掉
            if (ref[0].toggleDropDownVisible) {
              ref[0].toggleDropDownVisible(false);
            } else {
              ref[0].visible = false;
            }
          };
        }
      }
    },
	}
  }
</script>
<template> <div> <div class="card" style="margin-bottom: 5px;"> <div class="filter-row"> <div style="display: flex;align-items: center;"> <el-form-item label="项目名称" class="filter-item"> <el-input style="width: 200px;margin-right: 10px;" v-model="data.exportDate.formInline.user" placeholder="请输入"></el-input> </el-form-item> <el-form-item label="操作人" class="filter-item"> <el-select style="width: 200px;margin-right: 10px;" v-model="data.selectDate1.value" clearable placeholder="请选择"> <el-option v-for="item in data.selectDate1.options" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> <el-form-item class="filter-item" style=""> <el-button type="primary" @click="onSubmit">查询</el-button> </el-form-item> </div> </div> <div class="filter-row"> <el-form-item label="关联用例" class="filter-item"> <el-select style="width: 200px;margin-right: 10px;" v-model="data.selectDate2.value" clearable placeholder="请选择"> <el-option v-for="item in data.selectDate2.options" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> <el-form-item label="项目周期" class="filter-item"> <el-date-picker v-model="data.value1" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"> </el-date-picker> </el-form-item> <el-form-item> <el-button type="info" @click="onSubmit">重置</el-button> </el-form-item> </div> </div> <div class="card" style="margin-bottom: 5px;"> <el-button type="primary" plain icon="Plus" @click="handle" style="margin: 5px;">新增</el-button> <router-link to="/newproject">
最新发布
04-03
<think>好的,用户的问题是如何在Vue.js项目中利用Element Plus构建包含输入框、下选择器、日期范围选择器以及按钮事件处理的复杂表单过滤器。我需要一步步思考如何回答这个问题。 首先,我得回忆Element Plus的组件使用方式。用户提到的输入框、下选择器、日期范围选择器都是表单中常见的组件。Element Plus提供了el-input、el-selectel-date-picker等组件,这些都需要在模板中正确使用。 接下来,数据绑定是关键。Vue.js 3.x使用的是组合式API,所以需要用ref或reactive来定义响应式数据。比如,表单的各个字段应该用reactive包裹成一个对象,这样在模板中可以直接绑定。 然后,布局方面可能需要使用el-row和el-col来进行栅格布局,让表单元素在不同屏幕尺寸下自适应排列。同时,按钮可能需要右对齐,可以用flex布局或者el-row的justify属性来实现。 事件处理方面,用户需要按钮的点击事件,比如提交和重置。提交事件需要收集表单数据,可能发送请求或者过滤数据。重置事件需要将表单数据恢复初始状态,可能需要遍历表单对象,将每个字段设为空或默认值。 表单过滤器通常用于提交后触发数据过滤,所以需要将表单数据通过事件传递给父组件,或者直接在组件内部处理。这里可能需要使用emit来触发父组件的方法。 另外,用户可能还需要一些样式调整,比如间距、按钮的排列方式。Element Plus的组件支持size属性,可以统一设置表单元素的尺寸,保持UI一致性。 最后,验证用户是否可能需要表单验证功能,虽然问题中没有提到,但或许可以提一下使用el-form的验证规则,作为额外的建议。 现在需要确保代码示例正确,比如el-date-picker的type设置为daterange,v-model绑定正确的日期范围数组。下选择器el-select需要配合el-option,并且选项数据可能需要从后端获取,这里示例中可以静态定义。 在注意事项部分,要提到按需引入组件,避免打包体积过大。还有数据绑定的响应式处理,使用reactive或ref。以及事件处理中如何传递参数,可能使用emit。 相关问题部分,需要考虑用户可能进一步的问题,比如表单验证、Element Plus的其他表单组件、与后端交互的方式、重置功能的具体实现,以及如何优化表单布局。这些都是常见的后续问题。 现在整合这些思路,形成一个结构清晰的回答,分步骤讲解,并提供代码示例和注意事项,最后生成相关问题。</think>### 分步实现Vue3+Element Plus复杂表单过滤器 #### 一、基础结构搭建 1. 安装依赖并引入组件 ```bash npm install element-plus @element-plus/icons-vue ``` ```javascript import { ElInput, ElSelect, ElDatePicker, ElButton } from 'element-plus' import 'element-plus/dist/index.css' ``` 2. 创建响应式数据模型 ```javascript import { reactive } from 'vue' const filterForm = reactive({ keyword: '', status: '', dateRange: [], category: '' }) ``` #### 二、模板布局实现 ```html <template> <el-row :gutter="20" class="filter-container"> <!-- 关键词输入框 --> <el-col :span="6"> <el-input v-model="filterForm.keyword" placeholder="输入关键词" clearable /> </el-col> <!-- 状态下选择 --> <el-col :span="6"> <el-select v-model="filterForm.status" placeholder="选择状态" clearable > <el-option label="启用" value="1" /> <el-option label="停用" value="0" /> </el-select> </el-col> <!-- 日期范围选择 --> <el-col :span="8"> <el-date-picker v-model="filterForm.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" /> </el-col> <!-- 操作按钮--> <el-col :span="4" class="btn-group"> <el-button type="primary" @click="handleSubmit">查询</el-button> <el-button @click="handleReset">重置</el-button> </el-col> </el-row> </template> ``` #### 三、事件处理逻辑 ```javascript const emit = defineEmits(['filter-change']) const handleSubmit = () => { // 构造查询参数 const params = { ...filterForm, startDate: filterForm.dateRange[0], endDate: filterForm.dateRange[1] } delete params.dateRange emit('filter-change', params) } const handleReset = () => { Object.keys(filterForm).forEach(key => { if(Array.isArray(filterForm[key])) { filterForm[key] = [] } else { filterForm[key] = '' } }) } ``` #### 四、样式优化建议 ```css .filter-container { margin-bottom: 20px; padding: 15px; background: #f5f7fa; border-radius: 4px; .el-col { display: flex; align-items: center; } .btn-group { display: flex; justify-content: flex-end; gap: 10px; } } ``` ### 关键功能说明 1. **响应式数据绑定**:使用`reactive()`创建响应式对象,确保表单输入实时同步[^1] 2. **组件组合**:通过`<el-col>`实现栅格布局,适配不同屏幕尺寸 3. **日期范围处理**:`el-date-picker`的`type="daterange"`返回数组格式数据[^2] 4. **事件传递**:通过`emit`向父组件传递过滤参数,实现组件解耦 5. **重置功能**:遍历响应式对象属性进行初始化,处理数组类型字段 ### 高级优化建议 1. 添加防抖处理搜索输入 ```javascript import { debounce } from 'lodash-es' const handleSearch = debounce(() => { emit('filter-change', filterForm) }, 500) ``` 2. 集成表单验证 ```javascript const rules = { keyword: [{ max: 50, message: '不得超过50字符' }], status: [{ required: true, message: '请选择状态' }] } ``` 3. 保存查询条件到URL ```javascript import { useRoute, useRouter } from 'vue-router' const route = useRoute() const router = useRouter() // 初始化时读取URL参数 if(route.query.filter) { Object.assign(filterForm, JSON.parse(route.query.filter)) } // 提交时更新URL const handleSubmit = () => { router.push({ query: { filter: JSON.stringify(filterForm) } }) } ``` ### 注意事项 1. 按需引入组件减小打包体积 2. 复杂表单建议使用`<el-form>`组件包裹 3. 日期格式需统一处理(推荐day.js) 4. 移动端适配需调整栅格布局参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值