ElementUI Form resetFields

前言

在一次結合v-if/v-elseresetFields結合使用reset以後值不正常,看完源碼提了issue,而後被告知答案原來就在vue文檔裏,打臉打臉,所以記錄一次不看文檔,而且出問題不第一時間找文檔的教訓。html

結論

  1. 凡事先從文檔下手,用element-ui不是光看element-ui的文檔,還要看vue文檔
  2. Form組件resetFieldsdata值沒什麼關係,只跟Form-Item建立時的初始值有關。
  3. 使用v-if/v-else時,要先肯定組件是須要從新生成(用 key 管理可複用的元素),仍是能夠直接替換(新組件會使用舊組件的初始值,事實上這裏新舊是同一個組件更改了屬性)。
  4. 只有含有prop屬性,而且當前存在的組件纔會reset
  5. 若是Form組件不是一開始就建立,能夠用nextTick等待Form/Form-Item第一次建立完再resetFields。(這個其實跟組件沒多大關係)

事故現場

https://jsfiddle.net/s5ar1un3...vue

上面代碼切換組件後,執行resetFields重置值,結果重置的值爲別的組件綁定的初始值。git

事故緣由

Vue 會盡量高效地渲染元素,一般會複用已有元素而不是從頭開始渲染。

也就是說使用v-if/v-else時,雖然看似是多個組件切換,但其實是1個組件切換了自身的屬性。但問題的關鍵是,切換了vue的屬性,element-ui添加的屬性好比初始值並無換。github

解決

https://jsfiddle.net/s5ar1un3...element-ui

Vue 爲你提供了一種方式來表達「這兩個元素是徹底獨立的,不要複用它們」。只需添加一個具備惟一值的 key 屬性便可。

在事故現場上加上key值綁定。用 key 管理可複用的元素ide

resetFields過程

form.vueui

created() {
      this.$on('el.form.addField', (field) => {
        if (field) {
          this.fields.push(field);
        }
      }
      
      this.$on('el.form.removeField', (field) => {
        if (field.prop) {
          this.fields.splice(this.fields.indexOf(field), 1);
        }

      });
}

resetFields() {
        ...
        
        this.fields.forEach(field => {
          field.resetField();
        });
      },

form-item.vuethis

mounted() {
        if (this.prop) {
            this.dispatch('ElForm', 'el.form.addField', [this]);
            ...
            
            let initialValue = this.fieldValue;
            
            ...
            
            Object.defineProperty(this, 'initialValue', {
              value: initialValue
            });
            ...
        }
    }

    beforeDestroy() {
      this.dispatch('ElForm', 'el.form.removeField', [this]);
    }

    resetField() {
        ...

        this.validateDisabled = true;
        if (Array.isArray(value)) {
          prop.o[prop.k] = [].concat(this.initialValue);
        } else {
          prop.o[prop.k] = this.initialValue;
        }
    }
  1. Formcreated階段建立監聽,保存下當前Form-Item
  2. Form-Itemmounted判斷是否存在prop屬性,若是有,設置好初始值。
  3. Form組件resetFields其實是保存當前註冊上來的子組件Form-ItemresetField方法。
  4. Form-ItemresetField方法從新賦值爲this.initialValue。(以前事故緣由就是組件屬性更新initialValue值是不會變的)

參考

https://cn.vuejs.org/v2/guide...spa

https://github.com/ElemeFE/el....net

http://element-cn.eleme.io/#/...

相關文章
相關標籤/搜索