javascriptvue.jsvuejs3es6-proxy

Vue3: Add value to array or proxy


Let's start of with what I'm trying to do: I want to create an app in which I can list IP addresses and the user can add as many as they want. The app starts with 1 input field and with the press of a + button it should show the user an extra input field. I'm trying to add these IP addresses to an array which I can loop through later on. Vue 3 however turns my basic array into a proxy, I've tried to understand how to use proxies (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) but I can't find out how to add a basic item to the end of the array (proxy?). Using v-for I'm generating the amount of input fields based on how many items the array holds, but let's not get into that seeing that that is not the problem I'm facing.

Here's my first code snippet:

export default {
  data() {
    return {
      addresses: ["192", "193"],
    };
  },
  methods: {
    addIp() {
      this.addressses.push(194);
      // using 194 as an example but I'd like the new item to be empty
    },
}

For some reason however this is not adding 194 to the end of the array, it's not really doing anything. When I log the this.addresses it returns a proxy so Vue changed my basic array to a proxy, which is fine, I think. I've looked up how to add items to an array/proxy in Vue 3 (How can I push to an array (in Vue 3)?) but for some reason it doesn't work for my code.

I've also tried this.addresses.push({2: 194}) to see if I had to force the item to the second position, which broke my code.

Main questions that I have regarding this issue:

  1. Does the array really need to be changed to a proxy and why?
  2. What am I missing/doing wrong if I'm trying to add to a proxy?
  3. For later, how do I loop through a proxy?

EDIT:

<template>
<form class="serviceForm" @submit.prevent>
<div class="serviceFormServiceAddress">
  <div class="ipButtons">
    <label for="ipAddress">IP Adress</label>
    <button @click="removeIp">-</button>
    <button @click="addIp">+</button>
  </div>
  <input
    type="text"
    v-for="(address, index) in addresses"
    :key="index"
    v-model="addresses[index]"
    name="ipAddress"
    class="ipAddress"
  />
  <!-- change name to different id's -->
</div>
</form>
<button @click="generateServiceList">Test services</button>
</template>

Above is the code I'm using to generate the input fields. I'm using the console to check wether or not I have values in my array and if something is added to the array when I press the + button, should I do that somewhere else and if so: where?


Solution

  • If I understood you correctly, take a look at following snippet:

    const app = Vue.createApp({
      data() {
        return {
          addresses: ["192", "193"],
          ip: ''
        };
      },
      methods: {
        addIp() {
          this.addresses.push(this.ip);
          this.ip = ""
        },
      }
    })
    app.mount('#demo')
    <script src="https://unpkg.com/vue@3.2.29/dist/vue.global.prod.js"></script>
    <div id="demo">
      <div v-for="(address, i) in addresses" :key="i">
        {{ i + 1 }}<input v-model="addresses[i]" />
      </div>
      <input v-model="ip" />
      <button @click="addIp">Add</button>
      <p>{{ addresses }}</p>
    </div>