问题
阿里oss上图片带有时间戳,1分钟后图片就失效,前端切换页面通过浏览器缓存也能显示正常,但是无痕模式下就失败了,只有重新请求接口获得新图片
思考
想着前端请求同一个图片,显示还是直接用,并同时做图片缓存blob格式,下次用blob缓存内容来显示
组件 vc-image
vc-image , 封装的vue组件,已发布到 npmjs
安装
npm i @jser6/vc-image
使用
import vcImage from '@jser6/vc-image'
<vc-image src="https://www.baidu.com/img/flexible/logo/pc/peak-result.png" />
原理
缓存 blob 数据
const cacheBlobMap = new Map();
const vueCacheImage = {
props: {
src: {
type: String,
},
},
computed: {
realSrc() {
return cacheBlobMap.get(this.src) || this.src;
},
attrs() {
const attrs = this.$attrs;
delete attrs.src;
return attrs;
},
},
watch: {
src: {
handler(s) {
if (cacheBlobMap.get(s)) return;
if (/^(http|https|\/\/):/i.test(s)) {
const xhr = new XMLHttpRequest();
xhr.open("GET", s, true);
xhr.responseType = "blob";
xhr.onload = function () {
const file = new Blob([xhr.response]);
const blob = window.URL.createObjectURL(file);
cacheBlobMap.set(s, blob);
};
xhr.send();
}
},
immediate: true,
},
},
render() {
return <img src={this.realSrc} {...this.attrs} />;
},
};
vueCacheImage.install = function (Vue) {
Vue.component("vc-image", vueCacheImage);
};
export default vueCacheImage;
rollup打包 umd 和 esm
import babel from "rollup-plugin-babel";
import commonjs from "rollup-plugin-commonjs";
import vue from "rollup-plugin-vue";
import { terser } from "rollup-plugin-terser";
import del from "rollup-plugin-delete";
export default [
{
input: "./index.js",
output: [
{
file: "./lib/index.umd.js",
format: "umd",
name: "vc-image",
},
{
file: "./lib/index.es.js",
format: "es",
},
],
plugins: [
del({ targets: ["lib/*"] }),
vue(),
babel({
exclude: "node_modules/**",
runtimeHelpers: true,
}),
commonjs(),
terser(),
],
},
];
package.json
{
"name": "@jser6/vc-image",
"version": "1.0.5",
"description": "",
"main": "lib/index.umd.js",
"module": "lib/index.es.js",
"scripts": {
"build": "rollup -c"
},
"homepage": "https://github.com/rootjser/vc-image",
"keywords": [
"vue",
"cache",
"image",
"vc-image"
],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"@vue/babel-preset-app": "^5.0.8",
"rollup": "^2.78.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-vue": "^5.1.9",
"vue-template-compiler": "^2.7.8"
}
}
.babelrc
{
"presets": [["@vue/babel-preset-app"]]
}