通过字符串路径设置嵌套对象属性

时间:2019-04-13 10:47:08

标签: javascript vue.js vuejs2

我有3个选择框,我希望他们在选择时重置某个字段。如何使其动态化,以便可重复使用?

这是我的代码的摘录:

v-on:select="getDate('{{ route('api.v1.get.date') }}', 'input1', ['form.company.input2', 'form.company.input3'], $event)"

getDate(url, obj, obj2, event){

     let current = this

     current[obj] = ''
     current[obj2[0]] = ''
     current[obj2[1]] = ''

}

obj位于Vue实例的根级别(即current[obj])时,它将正确设置属性;但如果obj是嵌套对象,则不会。

4 个答案:

答案 0 :(得分:1)

尝试如下使用this.$set函数:

  this.$set(current,obj,'');
 this.$set(current,obj2[0],'');
 this.$set(current,obj2[1],'');

详细了解该功能here

答案 1 :(得分:1)

在JavaScript中,property accessors不允许嵌套的对象路径,这是点分隔的字符串中包含的内容。通过使用该字符串,实际上是在根Vue实例上创建属性,而不是设置嵌套属性,类似于以下内容:

this['form.company.input2'] = ''  // XXX: creates `form.company.input2` prop
this.form.company.input2 = ''     // sets `input2`

要按路径设置对象值,您可以创建一个方法,该方法使用对象路径通过this浏览当前Vue实例的数据属性:

methods: {
  getDate(url, obj, obj2, event) {
    this.setValue(obj, '')
    this.setValue(obj2[0], '')
    this.setValue(obj2[1], '')
  },
  setValue(path, value) {
    let obj = this
    const parts = path.split('.')
    while (parts.length > 1 && obj.hasOwnProperty(parts[0])) {
      obj = obj[parts.shift()]
    }
    obj[parts[0]] = value
  }
}

new Vue({
  el: '#app',
  data() {
    return {
      input1: 'input1',
      form: {
        company: {
          input2: 'input2',
          input3: 'input3'
        }
      }
    }
  },
  methods: {
    getDate(url, obj, obj2, event) {
      this.setValue(obj, '')
      this.setValue(obj2[0], '')
      this.setValue(obj2[1], '')
    },
    setValue(path, value) {
      let obj = this
      const parts = path.split('.')
      while (parts.length > 1 && obj.hasOwnProperty(parts[0])) {
        obj = obj[parts.shift()]
      }
      obj[parts[0]] = value
    },
    route(prop) {
      return prop
    }
  }
})
<script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <input v-model="input1">
  <input v-model="form.company.input2">
  <input v-model="form.company.input3">

  <button @click="getDate(route('api.v1.get.date'), 'input1', ['form.company.input2', 'form.company.input3'], $event)">
    Reset data
  </button>
</div>

或者,您可以使用一个库(例如lodash的{​​{3}}):

methods: {
  getDate(url, obj, obj2, event) {
    _.set(this, obj, '')
    _.set(this, obj2[0], '')
    _.set(this, obj2[1], '')
  }
}

new Vue({
  el: '#app',
  data() {
    return {
      input1: 'input1',
      form: {
        company: {
          input2: 'input2',
          input3: 'input3'
        }
      }
    }
  },
  methods: {
    getDate(url, obj, obj2, event) {
      _.set(this, obj, '')
      _.set(this, obj2[0], '')
      _.set(this, obj2[1], '')
    },
    route(prop) {
      return prop
    }
  }
})
<script src="https://unpkg.com/lodash@4.17.11/lodash.js"></script>
<script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <input v-model="input1">
  <input v-model="form.company.input2">
  <input v-model="form.company.input3">

  <button @click="getDate(route('api.v1.get.date'), 'input1', ['form.company.input2', 'form.company.input3'], $event)">
    Reset data
  </button>
</div>

答案 2 :(得分:0)

该库允许您使用嵌套的对象路径。

https://www.npmjs.com/package/vue-data-object-path

您的摘录应如下所示:

v-on:select="getDate('{{ route('api.v1.get.date') }}', 'input1', ['form.company.input2', 'form.company.input3'], $event)"

getDate(url, obj, obj2, event){

     let current = this

     current.$op.set(obj, '')
     current.$op.set(obj2[0], '')
     current.$op.set(obj2[1], '')

}

答案 3 :(得分:0)

对于路径为 object

string 中的获取设置嵌套值
function getNestedValue(obj, path){
    return path.split('.').reduce((o,i)=> o[i] || '', obj)
}

function setNestedValue(obj, path, value) {
    let i;
    path = path.split('.');
    for (i=0;i<path.length-1;i++) obj = obj[path[i]];
    obj[path[i]] = value
}

const obj = { a:{ b: [{c: 1 },{ d: 2 }] }}

setNestedValue(obj,'a.b.0.c',3)
console.log(getNestedValue(obj, 'a.b.0.c'))  // 3