Search code examples
javascriptvue.jsvuejs2vue-componentv-for

this.$refs[("p" + index)].focus is not a function


I'd like to turn a div into input box on click, so that the post (which is rendered inside a loop) can be edited.

Here is the button on the post:

<a @click="setFocusEdit(index)" v-if="isAuthor(post)" href="#" >Edit Me</a>

And the div concerned:

<div :ref="'p' + index"  class="post-description">
    {{post.description}}
</div>

The method:

  setFocusEdit(index) {
    console.log('focusing on', index);

    this.$refs['p' + index].focus();
  },

But I get this error:

Uncaught TypeError: this.$refs[("p" + index)].focus is not a function

How can I fix this?


Solution

  • Since you're using v-for you should use the ref attribute with static name like posts which gives you an array of the referenced elements

    new Vue({
      el: '#app',
      data: function() {
        return {
          posts: [{
              title: "post 1",
              content: "content 1"
            },
            {
              title: "post 2",
              content: "content 2"
            }
          ],
    
        }
      },
    
      methods: {
        setFocusEdit(index) {
    
    
          this.$refs.posts[index].focus();
        }
    
      },
      mounted() {
    
      }
    
    })
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
    
    
    
    <div id="app">
      <div class='col-md-4 mt-3' v-for="(post, index) in posts" :key="index">
        <textarea readonly ref="posts" class="post-description">
          {{post.content}}
        </textarea>
        <a @click.prevent="setFocusEdit(index)" href="#">Edit Me</a>
      </div>
    </div>