在一次結合v-if/v-else
與resetFields
結合使用reset
以後值不正常,看完源碼提了issue
,而後被告知答案原來就在vue
文檔裏,打臉打臉,所以記錄一次不看文檔,而且出問題不第一時間找文檔的教訓。html
element-ui
不是光看element-ui
的文檔,還要看vue
文檔Form
組件resetFields
跟data
值沒什麼關係,只跟Form-Item
建立時的初始值有關。v-if/v-else
時,要先肯定組件是須要從新生成(用 key 管理可複用的元素),仍是能夠直接替換(新組件會使用舊組件的初始值,事實上這裏新舊是同一個組件更改了屬性)。prop
屬性,而且當前存在的組件纔會reset
。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
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; } }
Form
在created
階段建立監聽,保存下當前Form-Item
。Form-Item
在mounted
判斷是否存在prop
屬性,若是有,設置好初始值。Form
組件resetFields
其實是保存當前註冊上來的子組件Form-Item
的resetField
方法。Form-Item
的resetField
方法從新賦值爲this.initialValue
。(以前事故緣由就是組件屬性更新initialValue
值是不會變的)https://cn.vuejs.org/v2/guide...spa