通过字符串路径设置嵌套对象属性 [英] Setting nested object property by string path
问题描述
我有 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屋!