亲宝软件园·资讯

展开

element-ui表单提交值清空

不会打代码 人气:3

需求的开始

一个表单,里面有很多表单项,然后需求通过特定的条件会触发某些表单项的显隐,条件会有很多很多,但是会有个问题,就例如:

所以,在a输入框隐藏状态,提交给后端的数据a输入框对应的值应该是空的才对,这么一看那我们的需求是不是就是:

但其实这样做并不好,让我们想想,就是例如一个开关,点一下控制10个表单项的显隐,用户好不容易填写了10个表单项,然后不小心点了一下开关把表单项给隐藏了,于是又重新点击开关把10个表单项给打开,但是却发现辛辛苦苦填写的10个表单项没有了,这谁受得了,所以我们的需求其实是这样的:

初步思路:标记方案

对应的我们的思路应该是这样:

有别的超简单的方案?

会有人觉得这个思路挺麻烦,那我只要提交的时候根据开关判断一下然后改变一下值不就好了吗,就例如:

let open = false; // 开关
let form = { // 表单的值
  name: '',
  age: '',
};
if (open === true) {
  submit(form); // 如果开关是开的,那就正常提交目前的表单,是改了什么值就什么值
} else {
  form.name = ''; // 如果开关是关的,那我手写这个代码把变量恢复空就好了
  form.age = '';
  submit(form);
}

突然是不是觉得上面那段代码已经可以解决问题了,之前的都是废话?其实并不是,开头就标明了,表单项有很多,200个?300个?,你觉得你也可以手写,那ok,如果加上20种不同的条件判断呢?

这个时候你要写多少代码,而且这样复杂度很高,代码也很难阅读,所以我才会想用标记记录。ok,否了这个“简单”的方案后,我们继续讨论之前的思路。

继续标记方案

分析如何实现

const hideTag = []

{ prop: 'name' } => const = tag = [{ prop: 'name' } ];

然后我们来分析一下怎么实现:

这个时候我们可以通过本身的显隐逻辑代码的时候,去增加代码,去通知到也页面这个属性要显示还是隐藏,但是实际上也是会混入非常多的代码在显隐逻辑的代码片段,所以不是很好

那样我们能不能这样,给我们的组件一个方法,当组件销毁和创建的时候发出一个事件,然后我们页面捕获这个事件再去逻辑,这个就很好,就不需要添加很多代码,

只需要在表单项组件的生命周期添加两个方法即可,因为你的属性这些内容,表单组件都是需要的所以都我们需要的属性名和显隐状态都有了

然后还需要引入一个 bus事件总线 ,来作为发射事件的导体,因为我的页面组件比较多,曾经比较复杂,如果页面层级相对简单的也可以使用自组件自带的 emit事件

具体如何实现在表单项组件添加显隐逻辑事件

(在项目里面element-ui的el-form-item组件)

复制的时候需要注意,el-form-item里面还引入了一个组件label-warp,这个也要复制过来,或者你把引导的代码修改一下:

之前:

import LabelWrap from './label-wrap';

修改:

import LabelWrap from ‘element-ui/packages/form/src/label-warp’

不然引用会报错,复制组件过来或者你修改引用路径都行,反正要保证原来代码的引用都是正常的

(label-warp组件)

// 引入eventBus
import {bus} from '@/bus';
// mounted添加显示事件
mounted() {
    // 两个个参数:
    // 第一个字段属性:name,或者多层的结构 person.age, human.yellow.name
    // 第二个是显隐状态:true就是显式,false就是隐藏
    bus.$emit('destroy-val', this.prop, true);
}
// destory添加隐藏事件
destroyed() {
   // 参数和显示是一样含义
    bus.$emit('destroy-val', this.prop, false)
  },
import Vue form 'vue;
export var bus = new Vue();
import {bus} from '@/bus';
export default {
  data() {
    return {
      hideTag: [],
    }
  },
  method: {
    // 根据显隐改变hideTag数组
    changeHideTag() {
                           // prop 就是属性名:name, human.yellow.name 
                           // isCreate 就是显隐:true就是显示,false就是隐藏
    bus.$on("destroy-val", (prop, isCreate) => {
      if (isCreate) {
        // 这个是显示的情况,所以我们要过滤一下,把对应隐藏的属性名去掉
        // prop: 'name', hideTag: ['name'] => hideTag: []
        this.hideTag = this.hideTag.filter(propName => propName !== prop );
      } else {
        // 这个是隐藏的情况,我们需要添加进入标记数组
        // prop: 'name', hideTag: [] => hideTag: ['name']
        props.forEach(prop => {this.hideTag.push(prop)});
      }
    });
  },
  }
}
import {bus} from '@/bus';
export default {
  data() {
    return {
      hideTag: [],
      // 表单对象
      form: {
        name: '',
        human: {
          yellow: {
            name: ''
          }
        }
      }
    }
  },
  method: {
// 根据hideTag清除对应的属性
    clearHiddenBlockVal() {
// 这是根据映射去清除fields对应值
        this.hideTag.forEach(item => {
// name => [name], human.yellow.name => [human, yellow, name]
            let propsStr = item.split(".");
// 这里的reduce最后不返回东西,目的是去到对象最后一层清空
            propsStr.reduce((pre, next, index, arr) => {
// 这里判断,如果是循环到属性的最后一层,也就是例如 obj.name => [obj, name] => 到name就是最后了,那就吧对应值清空
                if (index === arr.length - 1) {
                    pre[next] = '';
                } else {
                    return pre[next];
                }
            }, this.form);
            });
        },
  }
}
// 如果不知道reduce是怎么用法,地址在这里
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

结尾

加载全部内容

相关教程
猜你喜欢
用户评论