vue.js - Vue2点击事件为什么要点击两次才生效?
问题描述
有一个button,效果是点击后出现日期选择控件,可是为啥我需要点击两次button才能出来日期控件呢?求大神解疑。。控件是jquery的datetimepicker时间控件
下面是官方手册里那个列表渲染的例子我改了一下
HTML:
<div id="todo-list-example">
<input
v-model="newTodoText"
v-on:keyup.enter="addNewTodo"
placeholder="Add a todo"
>
<ul>
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:title="todo"
></li>
</ul>
</div>
JS:
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="selectDate($event)">X</button>\
</li>\
',
props: ['title'],
methods: {
selectDate: function(e){
// alert(111);如果换成alert点一次即能生效
this.$emit($(e.target).datetimepicker());
}
},
});
new Vue({
el: '#todo-list-example',
data: {
newTodoText: '',
todos: [
'Do the dishes',
'Take out the trash',
'Mow the lawn'
]
},
methods: {
addNewTodo: function () {
this.todos.push(this.newTodoText)
this.newTodoText = ''
}
}
});
给我的感觉是点击第一次在初始化,点击第二次才生效?怎么一次生效呢?
先谢过各位热心大神的回答...给了我很多思路,然而并没解决我的问题
这个问题我自己解决了,昨天才开始看Vue,新人一枚,谈谈我的思路。
首先感谢各位大神的热心解答。
一开始出现这个问题的时候,我在想是不是不能像过去写Jquery一样直接在<script></script>中绑定该控件?
$(document).on('click','#datetimepicker',function(){
....
})
难道像上面这样是绑不上的?于是我就在Vue实例中写了一个selectDate方法,点击按钮即触发它,然后再执行绑定。
selectDate: function(){
$(document).on('click','#datetimepicker',function(){
...
})
}
用这种方式的确能实现了,点击该元素后出现了日期控件。可是问题来了,怎么还需要点击两次?这谁受得了,不知道的还以为点了没反应呢。于是开始各种找问题,上百度搜了个遍,又来segament提问。
无奈开始找bug,怀疑是不是jquery和vue不兼容啊,然后把vue引用删了,的确好使。。。这就尴尬了,看来是Vue影响了控件的正常使用,可我还想用Vue啊,那只能继续翻Vue手册了。
然后猜想有可能是我点击后控件才开始初始化,所以点击第二次才生效?我一直确信应该是这么个情况,所以我就研究在哪里能提前把它初始化了或者说与元素绑定了。
于是看到了Vue的生命周期,Created、Updated、Mounted,全试了一个遍,发现的确是生命周期的问题,但只有Updated有效果,在Updated中绑定元素的话点击一次即可生效,到这里已经解决了我的问题,但是!Updated是数据有任何变化时候都会更新,也就是说假设打十个字,里面的函数会执行10次(可以console.log(123)看一下,确实执行了10遍),官方在手册中也提及了注意事项:
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
对于我这个小网页来说对性能其实影响不大,但这肯定不是我想要的结果。所以我继续看看Vue手册中还有没有类似我这种情况的案例。
Updated 不行,我又想到了$on和$emit,是Vue自带的事件监听和执行方法,试了一下,效果和之前selecDate方法的效果是一样的没卵用。
这问题已经困扰我两天了,想到最后,觉得这个问题归根到底还是和DOM的出现时间点也就是Vue的生命周期有关系,不管Vue怎么处理DOM,肯定是datetimepicker一定要挂载到DOM出现后才能生效,还是翻文档,偶然间看到生命周期里还有一个$nextTick方法。
用法参考Vue异步更新队列,它是这么说的:
将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
简单理解就是DOM更新完后执行回调,于是我调用这个方法,然后在这个回调里执行datetimepicker,由于DOM已经被加载到了网页,所以也不需要绑定了,直接执行即可,果然得到了预期的效果。
事后我觉得费这么大劲虽然解决了这个问题,但是我的思路应该还是不对,起码和Vue数据驱动、虚拟DOM的思想不契合,到现在我还没转变过来,日后等转变了再来谈谈这个问题吧。
这篇关于vue.js - Vue2点击事件为什么要点击两次才生效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!