【问题标题】:Focus input of freshly added item新添加项目的焦点输入
【发布时间】:2017-01-24 07:50:39
【问题描述】:

所以我有一个项目列表和通过 v-for 和 v-model 链接到每个项目的输入列表。

我单击一个按钮并将新项目添加到该列表中。我想关注与新添加的项目相关的输入。

不知道如何实现这个目标。

<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;
      })
    }
  }
})

这里是排序列表的小提琴 https://jsfiddle.net/sfL91r95/1/

谢谢

【问题讨论】:

标签: vue.js


【解决方案1】:

更新:受 pkawiak 评论的启发,这是一种基于指令的解决方案。我发现在bind 部分调用focus 不起作用;我不得不使用nextTick 来延迟它。

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>

原答案: 使您的输入成为一个组件,以便您可以给它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>

【讨论】:

  • 我会说这是最干净的方式。唯一的缺点是使用组件比简单的标记要重一些。但是“过早的优化是邪恶的”我想你也可以尝试使用指令来获得更轻量级的方法。无论如何+1
  • @pkawiak 我同意,指令是一个更好的主意。答案已更新。谢谢!
  • 太棒了。非常感谢。
  • this.el 现在未定义。而是使用 bind: function(el) 并使用 el
  • @Zout 对于 Vue 2 是正确的,但答案是在 Vue 1 中,其中的东西在 this
【解决方案2】:

我喜欢扩展 @Roy 的答案。 如果您使用的是任何 UI 框架,那么它将创建 DIV 并在 DIV 输入标记内创建,因此此 Snippet 将处理这种情况。

Vue.directive('focus-on-create', { 
    bind: function(el) { 
          Vue.nextTick(() => { 
              el.querySelector('input').focus()
          })
    }
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2017-12-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2012-06-08
    • 2014-09-08
    相关资源
    最近更新 更多