解决方案
- 新增自定义属性
data-origin-url
<div class="img-wrp">
<img
v-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; // 默认 src
if (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
属性)