{"id":148,"date":"2023-01-17T16:04:25","date_gmt":"2023-01-17T16:04:25","guid":{"rendered":"https:\/\/mrzebra.co.uk\/code\/?p=148"},"modified":"2023-01-17T16:04:25","modified_gmt":"2023-01-17T16:04:25","slug":"how-to-make-arrays-of-inputs-in-vue3","status":"publish","type":"post","link":"https:\/\/zebra-north.com\/code\/2023\/01\/17\/how-to-make-arrays-of-inputs-in-vue3\/","title":{"rendered":"How to Make Arrays of Inputs in Vue3"},"content":{"rendered":"\n<p>In the previous guide I showed <a href=\"https:\/\/zebra-north.com\/code\/2023\/01\/17\/how-to-make-a-compound-input-in-vue3\/\" data-type=\"post\" data-id=\"145\">how to make a compound input<\/a> for a person&#8217;s first and last name.  Suppose that we now want to show this input for a variable number of people, how should that be done?<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>We will start with a root data object that will contain all the data for our form, updated dynamically as the form inputs are changed.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\">const formData = {\n    people: [],\n};<\/code><\/pre>\n\n\n\n<p>The form will contain a list of &#8220;Person&#8221; inputs, and a button to add a new person.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-markup\">&lt;template&gt;\n  &lt;div style=&quot;border: 1px solid black&quot;&gt;\n    &lt;person\n      v-for=&quot;(person, index) in props.value&quot;\n      :key=&quot;index&quot;\n      :value=&quot;person&quot;\n    \/&gt;\n    &lt;button @click.prevent=&quot;addPerson&quot;&gt;Add Person&lt;\/button&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script setup&gt;\nimport Person from &quot;@\/Person.vue&quot;;\n\nconst props = defineProps({ value: Array });\n\nconst addPerson = function () {\n  props.value.push({ firstName: &quot;&quot;, lastName: &quot;&quot; });\n};\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>And the Person input simply contains the two text input fields:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-markup\">&lt;template&gt;\n  &lt;div&gt;\n    &lt;input type=&quot;text&quot; v-model=&quot;props.value.firstName&quot; \/&gt;\n    &lt;input type=&quot;text&quot; v-model=&quot;props.value.lastName&quot; \/&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script setup&gt;\nconst props = defineProps({ value: Object });\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Things to Note<\/h2>\n\n\n\n<p>It&#8217;s important to realise that the updating of data is handled by Vue3&#8217;s object reactivity API, and NOT by its event system.  This has two implications:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Form values are passed in the <code>:value<\/code> attribute, <strong>not<\/strong> in <code>v-model<\/code>.<\/li>\n\n\n\n<li>Form values passed in <code>:value<\/code> must be objects.  Simple types (strings, numbers) will not work.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide I showed how to make a compound input for a person&#8217;s first and last name. Suppose that we now want to show this input for a variable number of people, how should that be done?<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[],"class_list":["post-148","post","type-post","status-publish","format-standard","hentry","category-vue3"],"_links":{"self":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts\/148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/comments?post=148"}],"version-history":[{"count":2,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts\/148\/revisions"}],"predecessor-version":[{"id":150,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts\/148\/revisions\/150"}],"wp:attachment":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/media?parent=148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/categories?post=148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/tags?post=148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}