I have data record
record: {
address: {
city: ""
}
}
array of objects that describe field
fields: [
{
name: "address.city"
...
}
]
and try to generate form
<b-field
v-for="field in fields"
:key="field.name"
:label="field.label"
>
<b-input v-model="record[field.name]" />
</b-field>
and get object item with key like address.name
I understand that i should pass to v-model record[address][city]
but how to do it from dot delimited string?
Is it possible?
CodePudding user response:
const getPathInObject = (path, object) => {
const [current, ...rest] = path.split('.')
return rest.length === 0
? object[current]
: getPathInObject(rest.join('.'), object[current])
}
document.write(getPathInObject('a.b.c.d', { a: { b: { c: { d: 'hello' } } } }))
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
EDIT You can try something like this
const getPathInObject = (path, object) => {
const [current, ...rest] = path.split('.')
return rest.length === 0
? object[current]
: getPathInObject(rest.join('.'), object[current])
}
const setPathInObject = (path, object, value) => {
const splitPath = path.split('.')
let current
for (
current = object;
splitPath.length > 1;
current = current[splitPath.shift()]
);
current[splitPath[0]] = value
}
const makeDotSeparatedComputed = path => ({
[path]: {
get() { return getPathInObject(path, this)},
set(v) { setPathInObject(path, this, v) }
}
})
new Vue({
el: "#app",
data: {
a: { b: { c: { d: 'hello '}}}
},
computed: {
'a.b.c.d': makeDotSeparatedComputed('a.b.c.d')
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
Value of a.b.c.d = {{ a.b.c.d }}
<input v-model="a.b.c.d" />
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
I used :value
and @input
instead v-model
.
And lodash get
and set
<b-input
:value="get(data, field.name)"
@input="set(data, field.name, $event)"
/>