Laravel Mix环境下JScroll滚动加载后Vue组件未重新渲染问题
问题原因
- Vue实例的初始化扫描仅会在页面首次加载完成后执行1次,只会对初始化时刻已经存在于DOM树中的Vue组件标签完成编译、挂载和渲染
- JScroll插件异步拉取到后续页的卡片HTML后,是直接将新DOM片段插入到页面中,这部分新增DOM里的
<fav-button>等Vue自定义标签没有被已初始化的Vue实例扫描处理,因此只会保留原始的自定义标签结构,不会渲染为预期的组件样式和功能 - 你当前配置的JScroll回调仅做了删除分页元素的操作,没有补充Vue组件重新扫描的逻辑
解决办法
方案1(改造成本最低,适配现有技术栈)
在JScroll的加载回调中手动触发Vue扫描新插入的DOM区域即可:
- 先改造你打包用的
guest-app.js源码,把Vue挂载逻辑提取为全局可调用的方法,支持指定挂载区域:
// 原代码示例: // new Vue({ el: '#app' }) // 改造后代码: window.mountVueComponents = function (mountEl = '#app') { new Vue({ el: mountEl }) } // 首次加载时正常初始化全页组件 window.addEventListener('load', () => { mountVueComponents() })
- 修改JScroll初始化配置,新增挂载新内容的逻辑:
$('ul.pagination').hide(); $(function() { $('.scrolling-pagination').jscroll({ autoTrigger: true, padding: 0, nextSelector: '.pagination li.active + li a', contentSelector: 'div.scrolling-pagination', loadingHtml: '', callback: function() { $('ul.pagination').remove(); // 仅选中最新插入的卡片区域,扫描挂载其中的Vue组件 const newCardContainer = $('.scrolling-pagination').last(); mountVueComponents(newCardContainer[0]); } }); });
注意:不要直接选择全页容器执行挂载,否则会导致已渲染的组件重复绑定报错,仅处理新增的DOM区域即可。
方案2(符合Vue最佳实践,长期维护性更好)
放弃JQuery JScroll插件,改为使用Vue生态的无限滚动组件(比如vue-infinite-scroll),所有卡片数据拉取、DOM渲染逻辑完全交给Vue控制,从根源上避免JQuery和Vue混合操作DOM带来的各类兼容问题。
内容的提问来源于stack exchange,提问作者Zhu Xiao Yu
相关产品推荐
相关产品推荐

