【问题标题】:VueJS with Large Forms带有大型表单的 VueJS
【发布时间】:2017-01-02 07:06:36
【问题描述】:

我有一个包含 20 多个字段的巨大表单。我觉得我现在写的代码有很多冗余。最好的方法是什么?

<script>
new Vue({
    data : {
        user : {
            first_name : "",
            last_name : "",
            username : "",
            and 20+.........
        }
    }
});
</script>

<form>
    <input name="first_name" v-model="first_name">
    <input name="last_name" v-model="last_name">
    <input name="username" v-model="username">
    and 20+......... input fields
</form>

我觉得这样的东西会很好。用户对象将被动态创建。这可能吗?

<script>
new Vue({
    data : {
        user :  Object
    }
});
</script>

<form v-model="user">
    <input name="first_name">
    <input name="last_name">
    <input name="username">
    and 20+......... input fields
</form>

提前谢谢你

【问题讨论】:

  • 原则上您可以创建一个自定义指令,但它需要能够将v-model 绑定到所有输入,而 Vue 似乎没有提供一种以编程方式绑定指令的方法。
  • 你可以使用我的模块 vue-formation :)
  • 我知道这是一个老问题,但我已经更新了 Vue 2 的答案。

标签: forms binding model vue.js


【解决方案1】:

在 Vue 2 中完全重做

您的方法与通常的 Vue 方法相反,因为您希望在视图中布置数据结构并让 Vue 拾取它,而不是在数据中布置它并让 Vue 渲染它。如果您有想要实现的自定义布局,我可以看到这是多么可取。

非常规的需求需要非常规的解决方案,因此这种方法是非常规的。特别是,一般不建议子组件修改父组件中的数据。

也就是说,方法是创建一个组件,该组件将接受表单输入作为插槽,将父对象作为道具。在mounted 中,它获取所有具有name 属性的input 字段和

  1. 在父对象中创建成员,使用$set
  2. 为新创建的成员设置监视
  3. 添加input事件监听器完成双向绑定

您可能希望向组件添加更多道具,以使表单本身更加通用,但这为您提供了您正在寻找的功能。

Vue.component('autoBindingForm', {
  template: '<form><slot></slot></form>',
  props: ['createIn'],
  mounted() {
    const inputs = this.$el.querySelectorAll('input[name]');

    for (const i of inputs) {
      this.$set(this.createIn, i.name, i.value);
      this.$watch(`createIn.${i.name}`, (newVal, oldVal) => {
        i.value = newVal;
      });
      i.addEventListener('input', (e) => {
        this.createIn[i.name] = i.value;
      });
    }
  }
});

const vm = new Vue({
  el: '#app',
  data: {
    user: {}
  }
});

// Testing that binding works both ways
setTimeout(() => {
  vm.user.last_name = 'Set it';
}, 800);
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
  <auto-binding-form :create-in="user">
    <input name="first_name" value="hi">
    <input name="last_name">
    <input name="username">
    <div>{{Object.keys(user)}}</div>
    <div>{{Object.values(user)}}</div>
  </auto-binding-form>
</div>

【讨论】:

    【解决方案2】:

    怎么样

    data: {
      fields: { name: {v:''}, surname: {v:''}, ... }
    }
    

    <input v-for="(val, prop) in fields" :name="prop" v-model="val.v" />
    

    ?

    https://jsfiddle.net/gurghet/dhdxqwjv/1/

    【讨论】:

    • 这与发帖人要求的相反。他希望 DOM 创建数据,而不是数据创建 DOM。
    猜你喜欢
    • 2019-04-20
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多