Search code examples
javascripthtmlvue.jsemitvue-props

VueJS select object from list and display with function


I need to get the element I click which is displayed in a list. And print this element on a method which is on my vue instance throug mail-list tag which is on index.html

So I have Vue component which iterates json object and only prints two attributes from every element of it:

Vue.component('mail-list', {
  props: ['inboxmail'],
  methods: {
    selectmail: function(){
      this.$emit('selectmail', this.mail);
    }

  },
  template:
  `
  <div>
    <ul>
      <li v-for="i in inboxmail" @click="selectedmail">
      {{i.from}}:{{i.subject}}
      </li>
    </ul>
  </div>
  `
  });

After run this I have two elements displayed on my index.html which are:

I want to click one of this two elements and get the one I clicked. Then send it to vue method called setSelectedMail throug mail-list tag which is in index.html

index.html:

<div id="app">
        <mail-list v-bind:inboxmail="inbox" @selectmail="setSelectedMail($event)"></mail-list>
</div>

And finally, heres is the vue instance from where I want to get the selected mail:

let options = {
  el: "#app",
  data: {
    inbox: '',
    selectedMail:{}
  },
  methods: {
      setSelectedMail: function(mail){
          this.selectedMail = mail;
      }

  } //end methods
 }
//ViewModel (vm)
let vm = new Vue(options);

What am I doing wrong?


Solution

  • Check this. some corrections in your code.

    @click="selectmail(i.from)"
    
    methods: {
            selectmail: function(value) {
              this.$emit("selectmail", value);
            }
          }
    

    Demo with your code in codesandbox or Github.

    <!-- Complete code -->
    
    <!-- MailList -->
    
    <template>
      <div>
        <ul>
          <li v-for="i in inboxmail" @click="selectmail(i.from)" 
          v-bind:key="i.from">{{i.from}}:{{i.subject}}</li>
        </ul>
      </div>
    </template>
    
    <script>
    export default {
      name: "MailList",
      props: ["inboxmail"],
      methods: {
        selectmail: function(value) {
          this.$emit("selectmail", value);
        }
      }
    };
    </script>
    
    <!-- App.Vue -->
    
    <template>
      <div id="app">
        <mail-list v-bind:inboxmail="inbox" 
          @selectmail="setSelectedMail($event)">
        </mail-list>
    
        Selected: {{selectedMail}}
      </div>
    </template>
    
    <script>
    import HelloWorld from "./components/HelloWorld";
    import MailList from "./components/MailList";
    
    export default {
      name: "App",
      components: {
        HelloWorld, MailList
      },
      data: function(){
        return {
          inbox: [{
            from: '[email protected]',
            subject: 'Hi'
          },{
            from: '[email protected]',
            subject: 'How are you?'
          }],
          selectedMail: {}
        };
      },
      methods: {
        setSelectedMail: function(mail) {
          this.selectedMail = mail;
        }
      } //end methods
    };
    </script>
    
    <style>
    #app {
      font-family: "Avenir", Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>