JakHuang / form-generator

:sparkles:Element UI表单设计及代码生成器
https://jakhuang.github.io/form-generator
MIT License
9.02k stars 2.17k forks source link

使用parser解析json生成的表单中,如何在on事件中,响应式的修改表单的值 #188

Open czcz1024 opened 1 year ago

czcz1024 commented 1 year ago

在源码 /components/parser/example/index.vue中的例子里,有 __methods__: { clickTestButton1() { console.log( %c【测试按钮1】点击事件里可以访问当前表单: 1) formModel='formData', 所以this.formData可以拿到当前表单的model 2) formRef='elForm', 所以this.$refs.elForm可以拿到当前表单的ref(vue组件) , 'color:#409EFF;font-size: 15px' ) console.log('表单的Model:', this.formData) console.log('表单的ref:', this.$refs.elForm) }, 这样一段示例代码 我在这个方法中,通过使用 this.formData.mobile = 'xxxxx'对数据进行修改,通过console.log输出可以看到属性确实被赋值了 但是页面表单文本框中没有对应显示内容,似乎生成出来的表单不是响应式的 请问,在实现上,确实没有进行响应式实现,还是我的操作方式不对? 如何才能通过代码响应式的修改表单的值?

609067409 commented 1 year ago

this.formData是有双向绑定的,你看this对象上formData有劫持到get set方法就可以排除 没有出现响应式的原因是因为render.js-18行代码 dataObject.props.value = defaultValue 其实就是相当于 <input v-model="defaultValue"> 正常来说应该是<input v-model="formData.mobile"> 才对,作者这里这样写是为了让默认值能出现在input上,但是这样也导致了你直接修改formData它无法回显的问题。 所以要修改这个问题也很简单,在兼容之前的代码基础上: 1将formData传入render.js

//render.js
 props: {
    conf: {
      type: Object,
      required: true
    },
++    formData: {
++     type: Object
++ }
  }

2.将<input v-model="defaultValue"> 改为<input v-model="formData.mobile"> 并且兼容之前的代码

// 注意这里要加一个参数获取vModel
//render.js-53行:
++vModel.call(this, dataObject, confClone.__config__.defaultValue, confClone)
//render.js-17行:
++function vModel(dataObject, defaultValue, conf) {
++   dataObject.props.value = this.formData ? this.formData[conf.__vModel__] : defaultValue
       dataObject.on.input = val => {
    this.$emit('input', val)
  }
}

3.在Parse.vue-28将formData传入给render.js使用 Parse.vue-28 ++ <render conf={scheme} on={listeners} formData={this[this.formConf.formModel]}/>

然后再测试一下,你就会发现,好使了。

Reda011 commented 2 weeks ago

this.formData是有双向绑定的,你看this对象上formData有劫持到get set方法就可以排除 没有出现响应式的原因是因为render.js-18行代码 dataObject.props.value = defaultValue 其实就是相当于 <input v-model="defaultValue"> 正常来说应该是<input v-model="formData.mobile"> 才对,作者这里这样写是为了让默认值能出现在input上,但是这样也导致了你直接修改formData它无法回显的问题。 所以要修改这个问题也很简单,在兼容之前的代码基础上: 1将formData传入render.js

//render.js
 props: {
    conf: {
      type: Object,
      required: true
    },
++    formData: {
++     type: Object
++ }
  }

2.将<input v-model="defaultValue"> 改为<input v-model="formData.mobile"> 并且兼容之前的代码

// 注意这里要加一个参数获取vModel
//render.js-53行:
++vModel.call(this, dataObject, confClone.__config__.defaultValue, confClone)
//render.js-17行:
++function vModel(dataObject, defaultValue, conf) {
++   dataObject.props.value = this.formData ? this.formData[conf.__vModel__] : defaultValue
       dataObject.on.input = val => {
    this.$emit('input', val)
  }
}

3.在Parse.vue-28将formData传入给render.js使用 Parse.vue-28 ++ <render conf={scheme} on={listeners} formData={this[this.formConf.formModel]}/>

然后再测试一下,你就会发现,好使了。

大佬,我按照你的步骤试了下,但是在我这里,input框还是不能输入内容。

(debug发现其实是能输入值,只是不知道在什么地方值又被”重置“为undefined了)。

最后,我是在 Parse.vue-101 先将formData删除,然后再重新$set,发现能响应式赋值了。

Parse.vue-101 ++ this.$delete(this[this.formConf.formModel], scheme.__vModel__,);