你好,感谢作者提供的插件之前我也一直在使用。
周末准备用 Vue3
重构的此项目,重构完之后发现您已在 cli3
分支开发(还以为是脚手架呢,就没注意)。本来不打算写了,我看了您的实现方式思路和我不太一样,觉得可以讨论一下比较好的方案。
完整的代码地址
https://github.com/haiweilian/v-viewer/tree/next
删除指令的功能
我不太清楚作者之前是什么原因添加指令功能的,使用指令监听子元素的变化的方式会造成很多意外的问题,我也没再使用。在现在的版本有些不方便的是,不能自定义标签名、或者有时造成多余的层级嵌套、没有 API 调用的方式。
我想有其他的办法可以解决,比如指令使用 v-is
,它也会保留原始标签的属性。
<section v-is="'viewer'" :images="reactiveImages.asyncImages">
<img v-for="item of reactiveImages.asyncImages" :key="item" :src="item" width="200" height="200" />
</section>
组件使用函数
使用 render
函数,控制标签的标签名添加 tag
属性实现、还比较容易扩展。
return () =>
h(props.tag, { ref: $root }, slots.default && slots.default({ ...props })
);
这将渲染 section
标签。
<viewer tag="section">
<img v-for="item of reactiveImages.syncImages" :key="item" :src="item" width="200" height="200" />
</viewer>
API 调用的方式
使用 API
的方式,会很方便的处理某些问题,比如点击一个按钮然后预览图片,之前使用图片隐藏的方式太过麻烦也不太优雅。
期望调用方式如下,然后返回组件实例。
viewerInstance = ViewerPreview({
images: Images,
options: Options,
});
nextTick(() => {
viewerInstance.$viewer().view(1);
});
用 render
函数去渲染 component
组件,再返回组件实例。
function ViewerPreview(options: ViewerPreviewOptions) {
// ....
const vm = h(
ViewerComponent,
options,
options.images.map((src) => {
return typeof src === "string"
? h("img", { src })
: h("img", { src: src.src });
})
);
// ...
}
整体的方案
我还没有做过多的测试,或者是否有其他更好的方式去实现。如果觉得可行,我将提交一个新分支。