通过字符串路径设置嵌套对象属性 [英] Setting nested object property by string path

查看:26
本文介绍了通过字符串路径设置嵌套对象属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 3 个选择框,我希望它们在选择时重置某个字段.我怎样才能使它动态化,以便它可以重用?

这是我的代码的摘录:

v-on:select="getDate('{{ route('api.v1.get.date') }}', 'input1', ['form.company.input2', 'form.company.input3'], $event)"getDate(url, obj, obj2, 事件){让当前 = 这个当前[对象] = ''当前[obj2[0]] = ''当前[obj2[1]] = ''}

obj在Vue实例的根级(即current[obj])时,正确设置了属性;但当 obj 是嵌套对象时则不然.

解决方案

在 JavaScript 中,属性访问器 不允许嵌套的对象路径,这是点分隔字符串中的内容.通过使用该字符串,您实际上是在根 Vue 实例上创建一个属性,而不是设置嵌套属性,类似于:

this['form.company.input2'] = ''//XXX:创建`form.company.input2` propthis.form.company.input2 = ''//设置 `input2`

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

方法:{getDate(url, obj, obj2, 事件) {this.setValue(obj, '')this.setValue(obj2[0], '')this.setValue(obj2[1], '')},设置值(路径,值){让 obj = 这个const 部分 = path.split('.')而 (parts.length > 1 && obj.hasOwnProperty(parts[0])) {obj = obj[parts.shift()]}obj[parts[0]] = 值}}

new Vue({el: '#app',数据() {返回 {输入 1: '输入 1',形式: {公司: {输入 2: '输入 2',输入 3: '输入 3'}}}},方法: {getDate(url, obj, obj2, 事件) {this.setValue(obj, '')this.setValue(obj2[0], '')this.setValue(obj2[1], '')},设置值(路径,值){让 obj = 这个const 部分 = path.split('.')而 (parts.length > 1 && obj.hasOwnProperty(parts[0])) {obj = obj[parts.shift()]}obj[parts[0]] = 值},路线(道具){返回道具}}})

<script src="https://unpkg.com/vue@2.6.10"></script><div id="应用程序"><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)">重置数据

或者,您可以使用库(例如 lodash_.set):

方法:{getDate(url, obj, obj2, 事件) {_.set(this, obj, '')_.set(this, obj2[0], '')_.set(this, obj2[1], '')}}

new Vue({el: '#app',数据() {返回 {输入 1: '输入 1',形式: {公司: {输入 2: '输入 2',输入 3: '输入 3'}}}},方法: {getDate(url, obj, obj2, 事件) {_.set(this, obj, '')_.set(this, obj2[0], '')_.set(this, obj2[1], '')},路线(道具){返回道具}}})

<script src="https://unpkg.com/lodash@4.17.11/lodash.js"></脚本><script src="https://unpkg.com/vue@2.6.10"></script><div id="应用程序"><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)">重置数据

I have 3 select boxes, and I would like them to reset a certain field on select. How can I make it dynamic, so that it is reusable?

Here's an excerpt of my code:

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]] = ''

}

When obj is at the root level of the Vue instance (i.e., current[obj]), it sets the property correctly; but not when obj is a nested object.

解决方案

In JavaScript, property accessors do not allow nested object paths, which is what you have in the dot-separated string. By using that string, you're actually creating a property on the root Vue instance instead of setting a nested property, similar to this:

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

To set the object value by path, you could create a method that uses the object path to navigate the current Vue instance's data properties via this:

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>

Alternatively, you could use a library (such as lodash's _.set):

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>

这篇关于通过字符串路径设置嵌套对象属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆