【问题标题】:VueJS Dynamic v-model targetVueJS 动态 v-model 目标
【发布时间】:2019-12-27 08:11:27
【问题描述】:

我们正在创建一个表单,该表单通过输入的多个级别具有多个依赖项。所以如果parent1.input1 = 'test',那么child1.input1 应该等于测试。但是如果child1.input2 = 'more test',那么child1.input3应该等于'more test'

let v = new Vue({
  el:'#someEl',
  data:{
    parentval1:'foo',
    parentVal2:'bar',
    children:[
      {childVal1:'bax', modelAttr:'parentVal1'},
      {childVal2:'bix', modelAttr:'childVal1'},
      {childVal3:'boom', modelAttr:'childVal2'}
    ]
  },
  methods:{
    whichModelField(modelAttr){
      swith (modelAttr){
        case 'parentVal1':
          return xx; //should be bound to some data property if modelAttr === 'parentVal1'
          case 'childVal1':
           return yy; //should be bound to some other data property if modelAttr === 'childVal1'
      }
    }
  }
})
<div>
  <p id='parent'>
    <input id="1" placeholder="test" v-model="parentVal1"/>
  </p>
  <p id='child1' v-for="child in children">
    <input  placeholder="test" v-model="whichModelField(child.modelAttr)"/>
    
  </p>
</div>

我已经弄清楚如何动态绑定v-model attr 但是,我无法弄清楚如何使其在当前项目的上下文和父数据上下文(松散意义上的上下文)之间真正动态化。 IOW,我希望能够在数据对象的任何级别绑定到数据属性,但我无法弄清楚实现它的语法。

jsfiddle

【问题讨论】:

  • 您能否更新您的问题以包含 vue.js?还可以查看计算 vuejs.org/v2/guide/computed.html 您是否想在输入中输入一些内容,如果 value = something,请设置一个值?
  • vue 代码在小提琴中。我要问的是:我在一个表中有 10 行,每行在第一个单元格中都有一个输入。其中一些输入需要绑定到“父”数据对象的一个​​值,而一些输入需要绑定到“父”中的不同值。另一方面,有些需要绑定到同一“子”级别的其他输入。这一切都基于单元格 2 中每一行的属性值。所以,我希望遍历这些行,并根据该行的单元格 2 中的值,相应地绑定单元格中的输入。跨度>
  • 尝试更新sn-p澄清一下
  • v-model 用于 2 方向绑定,我认为您不希望孩子会更新父母。你应该使用一个方向绑定::value=""
  • @ZivBen-或者谢谢,我会记住这一点。但是,OTOH,规范说我们应该禁用依赖字段的输入,因此数据在这方面受到保护。

标签: javascript vue.js binding


【解决方案1】:

Vue 仍然是 Javascript - 您可以使用字符串访问属性

let v = new Vue({
  el:'#someEl',
  data(){
    const self = this
    return {
    parentval1:'foo',
    parentVal2:'bar',
    children:[
      {childVal1:'bax', modelAttr:'parentVal1'},
      {childVal2:'bix', modelAttr:'childVal1'},
      {childVal3:'boom', modelAttr:'childVal2'}
    ],
    whichModelField: {
      get parentVal1(){
           return self.parentval1
      },
      set parentVal1(val){
           self.parentval1 = val
      },
      get childVal1(){
        return self.children[0]['childVal1']
      },
      set childVal1(val){
        self.children[0]['childVal1'] = val
      },
      get childVal2(){
        return self.children[1]['childVal2']
      },
      set childVal2(val){
        self.children[1]['childVal2'] = val
      }
      
    }}
  }
})
.as-console-wrapper {
  height: 0px !important
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="someEl">
  <p id='parent'>
    <input id="1" placeholder="test" v-model="whichModelField['parentVal1']"/>
  </p>
  <p id='child1' v-for="child in children">
    <input  :placeholder="child.modelAttr" v-model="whichModelField[child.modelAttr]"/>
    
  </p>
</div>

【讨论】:

  • @monkeydeus 像这样,或者我应该放置一些 getter,setter 代理以使其更具动态性?
  • 谢谢,我没有考虑过只是一个映射数组,我会这样做,看看是否可行。根据我链接到的小提琴,您似乎应该能够使用“whichField”类型的处理器来做到这一点,但我无法弄清楚如何使这种方法完全动态地工作。如果我在 $data 属性中进行硬编码,我可以将模型绑定到下一级属性,或者我可以使用“this”的等效项来绑定到当前迭代的其他属性,但不知道如何即时切换
  • 这似乎不起作用。 JSFiddle:jsfiddle.net/monkeydeus/dpjcsnLy/17 这些字段只是作为字符串绑定到查找 val,而不是字符串应该指向的对象属性。
  • @monkeydeus - 我看到需要 getter setter 代理 ;) 此刻我正在移动
  • 感谢您的帮助。我不确定我是否已完全拨入,但是,您的工作向我展示了我面临的一个问题是让我的开关返回一个字符串,而不是实际的对象属性。我现在在这里有一个基本版本:jsfiddle.net/monkeydeus/dpjcsnLy
【解决方案2】:

我将第一个孩子和其他孩子分开,因为您只想在第一个孩子的父母中进行双向绑定,您不希望孩子们会更新父母:

new Vue({
  el:'#app',
  data:{
    parent:'foo',
    child:'bar',
    children:[
      {placeHolder:'bax'},
      {placeHolder:'bix'},
      {placeHolder:'boom'}
    ]
  },
  watch:{
      parent: function(value){debugger; this.child = value}
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input id="1" v-model="parent" placeholder="test"/>
  <input v-model="child"
         :id="0"
         :placeholder="children[0].placeHolder" />

  <input  v-for="i in children.length - 1"
         :value="child"
         :id="i + 1"
         :placeholder="children[i].placeHolder" />
</div>

【讨论】:

    【解决方案3】:

    这是你要找的吗:

    new Vue({
        el:'#app',
        data:{
            parent:'',
            child:''
        },
        watch:{
            parent: function(value){this.child = value}
        }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <p id='parent'>
        <input id="1" placeholder="test" v-model='parent'/>
      </p>
      <p id='child1'>
        <input id="1" placeholder="test"  v-model='child' :value='parent'/>
        <!-- 1 and parent>input#1 should be bound to same value -->
        <input id="2" placeholder="more test" :value='child'/>
        <!-- 2 and 3 should be bound to same value -->
        <input id="3" placeholder="more test" :value='child'/>
      </p>
    </div>

    【讨论】:

    • 我不这么认为。我已经清理了我的 sn-p 一点点。基本上,每一行(child,in children)都会有一个属性'modelAttr'。根据该行的“modelAttr”值,输入应绑定到不同的数据属性。它可能是数据对象的顶级(父)属性,或者,它可能绑定到另一个子对象的另一个属性。因此,v-model 绑定必须是完全动态的,可能基于某个函数的输出。
    猜你喜欢
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2020-06-08
    • 2019-04-16
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 2018-11-04
    相关资源
    最近更新 更多