So I have a list of items and list of inputs linked to each item via v-for and v-model.
I click a button and add new item to that list. I want to focus input which is linked to newly added item.
Can't figure out how to achieve this goal.
<div id="app">
  <div v-for="item in sortedItems">
    <input v-model="item">
  </div>
  <button @click="addItem">
    add
  </button>
</div>
new Vue({
  el: '#app',
  data: {
    items: []
  },
  methods: {
    addItem: function() {
      this.items.push(Math.random());
    }
  },
  computed: {
    sortedItems: function() {
      return this.items.sort(function(i1, i2) {
        return i1 - i2;
      })
    }
  }
})
Here's fiddle with sorted list https://jsfiddle.net/sfL91r95/1/
Thanks
Update: inspired by pkawiak's comment, a directive-based solution. I found that calling focus in the bind section didn't work; I had to use nextTick to delay it.
Vue.directive('focus-on-create', {
  // Note: using Vue 1. In Vue 2, el would be a parameter
  bind: function() {
    Vue.nextTick(() => {
      this.el.focus();
    })
  }
})
new Vue({
  el: '#app',
  data: {
    items: []
  },
  methods: {
    addItem: function() {
      this.items.push(Math.random());
    }
  },
  computed: {
    sortedItems: function() {
      return this.items.sort(function(i1, i2) {
        return i1 - i2;
      })
    }
  }
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<div id="app">
  <div v-for="item in sortedItems">
    <input v-focus-on-create v-model="item">
  </div>
  <button @click="addItem">
    add
  </button>
</div>
Original answer:
Make your input a component so that you can give it a ready hook.
const autofocus = Vue.extend({
  template: '<input v-model="item" />',
  props: ['item'],
  ready: function() {
    this.$el.focus();
  }
})
new Vue({
  el: '#app',
  data: {
    items: []
  },
  methods: {
    addItem: function() {
      this.items.push(Math.random());
    }
  },
  components: {
    autofocus
  },
  computed: {
    sortedItems: function() {
      return this.items.sort(function(i1, i2) {
        return i1 - i2;
      })
    }
  }
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<div id="app">
  <div v-for="item in sortedItems">
    <autofocus :item="item"></autofocus>
  </div>
  <button @click="addItem">
    add
  </button>
</div>
I Like to extend @Roy's answer. if you are using any UI framework then it will create DIV and within the DIV input tag will be created so this Snippet will handle that case.
Vue.directive('focus-on-create', { 
    bind: function(el) { 
          Vue.nextTick(() => { 
              el.querySelector('input').focus()
          })
    }
})
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With