解决方案
- 新增自定义属性
data-origin-url
<div class="img-wrp"><imgv-lazy="img.url":data-origin-url="img.url"/>
</div>
- viewer.js 修改
options.url
属性
其中 url 支持传入 string | function
const options = merge({url(image) {if (!image) return '';const url = image.getAttribute('large') || image.getAttribute('src');return url;}
}, configs.options || {});
gallery.current = new Viewer(dom, options);
综上,完美解决两者冲突的问题,亲测可用
问题分析
viewer.js 执行原理是在当前容器中,查找所有的 img 标签,并获取其 src 属性进行维护。
1. viewer.js
viewer.js 初始化时,获取 image.src 属性,如果为空,则对该dom不绑定任何事件
// viewer.js 源码
const images = [];forEach(isImg ? [element] : element.querySelectorAll('img'), (image) => {if (isFunction(options.filter)) {if (options.filter.call(this, image)) {images.push(image);}} else if (this.getImageURL(image)) {images.push(image);}
});// 获取 image src
getImageURL(image) {let { url } = this.options; // 默认 srcif (isString(url)) {url = image.getAttribute(url);} else if (isFunction(url)) {url = url.call(this, image);} else {url = '';}return url;
}
2. v-lazy
而 v-lazy 插件会在 img 标签上先挂载一个 data-src 自定义属性,等 img 加载完成之后,再进行替换
raw HTML
<div v-lazy-container="{ selector: 'img' }"><img data-src="//domain.com/img1.jpg"><img data-src="//domain.com/img2.jpg"><img data-src="//domain.com/img3.jpg">
</div>loaded(data-src替换为src)
<div v-lazy-container="{ selector: 'img' }"><img src="//domain.com/img1.jpg"><img src="//domain.com/img2.jpg"><img src="//domain.com/img3.jpg">
</div>
如果两个组件分开使用,功能都是正常运行的。一旦组合使用,这两者的逻辑就会有冲突(viewer.js 初始化时获取 img.src
,v-lazy 只有在img loaded 时,才会挂载 src
属性)