Search code examples
vue-componentvue-cli-3

How to pass parameter of a function with v-for in Vue?


I am trying to pass a parameter to a function by looping through an the array items with v-for.

<template>
  <v-app>
    <v-app-bar app>
      <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
      <v-spacer></v-spacer>
      <h1 ref="y"></h1>
    </v-app-bar>
    <v-content>
      <router-view />
      <v-navigation-drawer v-model="drawer" class="x">
        <v-list-item
          v-for="item in items"
          :key="item.unidade"
          :to="item.link"
          :@click="change(item.method)"
        >{{item.unidade}}</v-list-item>
      </v-navigation-drawer>
    </v-content>
  </v-app>
</template>

<script>
export default {
  name: "App",

  data: () => ({
    items: [
      { unidade: "IPE", link: "/ipe", method: "IPE" },
      { unidade: "DCSI", link: "/dcsi", method: "DCSI" },
      { unidade: "RT", link: "/rt", method: "RT" }
    ],
    drawer: false
  }),
  methods: {
    change(val) {
      console.log(val);
      this.$refs.y.innerText = val;
    }
  }
};
</script>
<style lang="stylus" scoped>
.x {
  position: absolute;
}
</style>

I want the parameter in items arrray to be passed to change(val) method giving each v-list-item a distinct event listener. Then I want h1 with the ref="y" to change it's text based on the v-list-item I click. But so far I am getting the browser error of "Error in render: "TypeError: Cannot set property 'innerText' of undefined""


Solution

  • Instead of setting the innerText of the <h1> you could instead bind the innerText to a reactive variable. You could create a variable in data that could store the selected method and then bind that to the innerText using {{}} syntax. Doing it this way would be more inline with Vue best practices. Let me show you what I mean.

    <template>
      <v-app>
        <v-app-bar app>
          <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
          <v-spacer></v-spacer>
          <h1 ref="y">{{ selectedMethod }}</h1> 
        </v-app-bar>
        <v-content>
          <router-view />
          <v-navigation-drawer v-model="drawer" class="x">
            <v-list-item
              v-for="item in items"
              :key="item.unidade"
              :to="item.link"
              :@click="change(item.method)"
            >{{item.unidade}}</v-list-item>
          </v-navigation-drawer>
        </v-content>
      </v-app>
    </template>
    
    <script>
    export default {
      name: "App",
    
      data: () => ({
        items: [
          { unidade: "IPE", link: "/ipe", method: "IPE" },
          { unidade: "DCSI", link: "/dcsi", method: "DCSI" },
          { unidade: "RT", link: "/rt", method: "RT" }
        ],
        selectedMethod: '', // Initially blank
        drawer: false
      }),
      methods: {
        change(val) {
          this.selectedMethod = val; // Update the value of selectedMethod
        }
      }
    };
    </script>
    <style lang="stylus" scoped>
    .x {
      position: absolute;
    }
    </style>

    Hope this helps!