Vue与jQuery插件混用,Jquery的事件无法响应怎么解决?

问题复现:使用axios请求后台数据,然后在前端渲染一个列表,如果在页面里使用jquery监听列表节点的话,此时jquery的click事件是无效的,点击列表的dom节点没有任何反应,因为监听dom事件的时候,页面还没渲染好。

如果要监听dom的变化,必须在vue重新渲染dom之后使用$().click

方法一
使用MutationObserver全局对象去监听,我没试过。

方法二
在vue的生命周期 updated()中使用jquery监听。调用updated()的时机:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。注意:如果变量改变导致Dom需要重新渲染的话,updated()可能会被调用多次。

方法三
vue里面本身带有两个回调函数: 一个是 Vue.nextTick(callback),当数据发生变化,更新后执行回调。 另一个是 Vue.$nextTick(callback),当dom发生变化,更新后执行的回调。 栗子:

1
2
3
4
5
...
<ul id="demo">
<li v-for="item in list">{{item}}</div>
</ul>
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
new Vue({
el:'#demo',
data:{
list=[0,1,2,3,4,5,6,7,8,9,10]
},
methods:{
push:function(){
this.list.push(11);
this.nextTick(function(){
alert('数据已经更新')
});
this.$nextTick(function(){
alert('v-for渲染已经完成')
})
}
}
})

同理,如果是通过axios请求数据,则在axios的响应回调中使用nextTick


在说下nextTick:

关于nextTick,官方给的定义是:

将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新……

也就是说,nextTick的应用场景是在DOM生成之后,当你改变一个数据后,想对这个数据所对应的DOM进行操作,这个时候你就需要用到nextTick

这里如果你有点迷惑,那么建议你了解下vue异步队列的概念。大致是这个意思,就是当你改变的一个数据之后,vue检测到这个数据的变化,回去更新相应的视图,但是这个更新视图的操作需要排队,并不是马上就更新,即它是异步的。也就意味着,这个更新操作和你当前执行的函数(你更改数据的这个函数)并不在同一个栈里面,它可能会等你执行完当前函数里面的语句后,才去执行DOM更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Vue.component('example', {
template: '<span>{{ message }}</span>',
data: function () {
return {
message: '没有更新'
}
},
methods: {
updateMessage: function () {
this.message = '更新完成'
// 这个时候已经执行了数据改变的操作,可能会误以为此时DOM中的textContent已经变成'更新完成',其实并没有。正如上文所说的这个操作是异步的,它还在排队。
console.log(this.$el.textContent)
this.$nextTick(function () {
// 这里就是nextTick的用处,用一个异步回调,他会等到DOM更新后,再去执行相应的DOM操作。
console.log(this.$el.textContent) // => '更新完成'
})
}
}
})