A back end business object contains a custom attributes data structure that allows client to add key/value pairs for persistence in the database. For example: Map<String, String> customAttributes;
UI example: (With the ability to add additional rows)
Within the vue's data function, I have a placeholder for this data:
data() {
return {
customAttributes: {},
...
}
But I cannot figure out a way to bind the UI inputs to the customAttributes
object such that adding a new row (attribute) adds a corresponding key and value to it.
Is there an alternative way of handling this?
CodePudding user response:
I wouldn't use a Map
for this as Vue will have a hard time tracking object keys if they can be readily altered. Seems more appropriate to use something like Array<{ key: string, value: string }>
If you do need the map version, you can easily compute it from the array
const model = { key: "", value: "" }
new Vue({
el: "#app",
data: () => ({
attributes: [{
key: "GRADLE_HOME",
value: "/usr/local/gradle"
}, {
key: "JAVA_HOME",
value: "/usr/lib/jvm/whatever"
}]
}),
computed: {
attributeMap: ({ attributes }) =>
Object.fromEntries(attributes.map(({ key, value }) => [ key, value ]))
},
methods: {
add () {
this.attributes.push({...model})
},
del (index) {
this.attributes.splice(index, 1)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<table border="1">
<thead><tr><th>Name</th><th>Value</th></tr></thead>
<tbody>
<tr v-for="(attr, index) in attributes" :key="index">
<td><input v-model="attr.key"/></td>
<td>
<input v-model="attr.value" />
<button @click="del(index)">×</button>
</td>
</tr>
</tbody>
<tfoot>
<tr><td colspan="2"><button @click="add">Add Attribute</button></td></tr>
</tfoot>
</table>
<pre>attributeMap = {{ attributeMap }}</pre>
</div>