Search code examples
vue.jsv-for

v-for loop not working with imported array


I have 2 files one called clients.js with data and one called clients.vue and I would like to import the data and list it out in a table in the clients.vue file; but I can not access it when importing.

It's working fine if I move the array in to the clients.vue-file (so without import).

My code looks (simplified) like this:

Clients.vue

<template>
  <div>
    <table>
      <tbody>
        <tr v-for="client in clients">
          <td>{{ client.ClientName }}</td>
          <td>{{ client.ClientId }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
import clients from "./data/clients.js";

export default {};
</script>

And my clients.js file:

export default {
  data () {
    return {
      clients: [
        {
          ClientName: 'testname1',
          ClientId: 1
        },
        {
          ClientName: 'testname2',
          ClientId: 2
        }
      ]
    }
  }
}

I know probably have "activate" the imported array somehow, but i do not know how.


Solution

  • You would have to expose a property defined in your component's data object.

    You have imported the clients but not injected it into your data of Clients.vue.

    Change the Clients.vue like so.

    <script>
    import clients from "./data/clients.js";
    
    export default {
      ...clients
    };
    

    This will inject the clients into Client.vue. Then you can use that in your template of Client.vue.

    Alternative:

    However this is not a good pattern in terms of readability.

    It would be better to have a property in the component itself and then set the property in mounted hook.

    You can do so in the following way:

    <template>
      <div>
        <table>
          <tbody>
            <!-- use key when iterating -->
            <tr v-for="client in clients" :key="client.ClientId"> 
              <td>{{ client.ClientName }}</td>
              <td>{{ client.ClientId }}</td>
            </tr>
          </tbody>
        </table>
      </div>
    </template>
    
    <script>
    import clients from "./data/clients.js";
      export default {
        clients: [] // initial value
      },
      mounted () { // setting clients in mounted 
        this.clients = { ...clients } // use Vue.set if this is a deep nested object
      },
    </script>
    
    <style lang="scss" scoped></style>
    

    Mixin way

    If you intend to use clients.js as an mixin.

    Then change your script to this:

    <script>
    import clients from "./data/clients.js";
    export default {
      mixins: [clients],
    }
    </script>