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

848 阅读1分钟

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发生变化,更新后执行的回调。 栗子:

...
<ul id="demo">
    <li v-for="item in list">{{item}}</div>
</ul>
...
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更新。

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) // => '更新完成'
      })
    }
  }
})