[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"donations-sidebar":3,"$fiMMqz-SH16I70wc9aPOpkOvmZy8n6D3fri78yAQkGfo":4,"posts-{\"page\":1,\"pageSize\":10,\"tagId\":\"9321a12e-ea72-49a9-a32d-5566149f812f\"}":9},[],{"id":5,"name":6,"slug":6,"createdAt":7,"updatedAt":8},"9321a12e-ea72-49a9-a32d-5566149f812f","图片压缩","2022-08-02T00:37:47.000Z","2023-02-08T02:49:14.000Z",{"list":10,"total":64,"page":65,"pageSize":66},[11,31,47],{"id":12,"title":13,"slug":13,"content":14,"excerpt":13,"coverImage":15,"status":16,"isPinned":17,"pinnedAt":18,"viewCount":19,"publishedAt":20,"createdAt":20,"updatedAt":21,"category":22,"author":26,"tags":29},"b2c46bf6-d971-4cce-b21b-052dbea8e8a2","v-html使用img点击实现放大效果","## 代码实现\n```js\n\u002F**\n * JS获取html代码中所有的图片地址\n * @param htmlstr\n * @returns arr 数组\n *\u002F\n\nexport function getimgsrc(htmlstr) {\n    let reg = \u002F\u003Cimg.+?src=('|\\\")?([^'\\\"]+)('|\\\")?(?:\\s+|>)\u002Fg;\n    let arr = [];\n    let tem = 0;\n    \u002F\u002Feslint-disable-next-line\n    while ((tem = reg.exec(htmlstr))) {\n        arr.push(tem[2]); \u002F\u002F eslint-disable-line\n    }\n\n    return arr;\n}\n\n```\n\n\n\n```vue\n\u003Ctemplate>\n    \u003Cdiv class=\\\"image-expansion\\\" :class=\\\"classArr\\\">\n        \u003Cdiv @click.stop=\\\"hanldeImage($event)\\\" v-html=\\\"formatHtmlData\\\">\u003C\u002Fdiv>\n\n        \u003Cel-image-viewer\n            v-if=\\\"imgPreviewUrl\\\"\n            :initial-index=\\\"subscript\\\"\n            :src=\\\"imgPreviewUrl\\\"\n            :on-close=\\\"closeViewer\\\"\n            :url-list=\\\"imgList\\\"\n        >\u003C\u002Fel-image-viewer>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport { getimgsrc } from '..\u002F..\u002Futils\u002Fgetimgsrc';\nimport ElImageViewer from 'element-ui\u002Fpackages\u002Fimage\u002Fsrc\u002Fimage-viewer';\nexport default {\n    components: {\n        ElImageViewer\n    },\n    props: {\n        htmlData: {\n            type: String,\n            default: () => {\n                return '';\n            }\n        },\n        classArr: {\n            type: Array,\n            default: () => {\n                return ['min'];\n            }\n        },\n\n        isArticle: {\n            type: Boolean,\n            default: () => {\n                return false;\n            }\n        }\n    },\n    data() {\n        return {\n            imgList: [],\n            formatHtmlData: '',\n            imgPreviewUrl: '',\n            subscript: 0\n        };\n    },\n    computed: {},\n\n    watch: {\n        \u002F\u002F监听数据，防止数据不更新\n        htmlData: {\n            handler(newName, oldName) {\n                \u002F\u002F判断是否为文章\n                if (this.isArticle) {\n                    newName ? (this.formatHtmlData = newName.replace(\u002F(\u003C([^>]+)>)\u002Fgi, '').replace(\u002F[\\\r\\\n]\u002Fg, '')) : '';\n                } else {\n                    \u002F\u002F剔除strong和p标签\n                    newName ? (this.formatHtmlData = newName.replace(\u002F(\u003C\\\u002F?strong.*?>)|(\u003C\\\u002F?p.*?>)\u002Fg, '')) : '';\n\n                    \u002F\u002F获取html全部图片，push成图片数组\n                    this.imgList = Object.values(getimgsrc(this.formatHtmlData));\n                    \u002F\u002F获取图片下标\n                    let subscript = this.imgList.indexOf(this.imgPreviewUrl);\n                    this.subscript = subscript > -1 ? subscript : 0;\n                }\n            },\n\n            immediate: true\n        }\n    },\n\n    mounted() {},\n\n    methods: {\n        \u002F\u002F监听点击事件\n        hanldeImage(event) {\n            if (event.target.nodeName === 'IMG' || event.target.nodeName === 'img') {\n                \u002F\u002F获取点击的图片url,decodeURIComponent转码一下，防禁url转码\n                this.imgPreviewUrl = decodeURIComponent(event.target.currentSrc);\n\n                \u002F\u002F获取图片下标\n                let subscript = this.imgList.indexOf(this.imgPreviewUrl);\n                this.subscript = subscript > -1 ? subscript : 0;\n\n                \u002F\u002F禁止遮罩层后面的内容滚动\n                document.documentElement.style.overflowY = 'hidden';\n            } else {\n                this.$emit('goDetail');\n            }\n        },\n\n        \u002F\u002F关闭弹框\n        closeViewer() {\n            this.imgPreviewUrl = '';\n            \u002F\u002F恢复遮罩层后面的内容滚动\n            document.documentElement.style.overflowY = 'auto';\n        }\n    }\n};\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\\\"scss\\\" scoped>\n.image-expansion {\n}\n\n.min {\n    \u002Fdeep\u002F img {\n        cursor: pointer;\n        height: 28px;\n        padding: 0 10px 3px;\n    }\n}\n\n.max {\n    \u002Fdeep\u002F img {\n        cursor: pointer;\n    }\n}\n\n.class1 {\n    \u002Fdeep\u002F div {\n        font-size: 15px;\n        font-family: Microsoft YaHei;\n        font-weight: 400;\n        color: #888888;\n        line-height: 30px;\n    }\n}\n\u003C\u002Fstyle>\n\n\n```\n","https:\u002F\u002Fcdn.xiaolong0418.com\u002Fmyblog\u002Fimages\u002Fc77c3fb113d1ab2f67e7afba1ca33b95.png","PUBLISHED",false,null,1579,"2023-01-10T07:22:29.000Z","2026-06-28T18:44:45.012Z",{"id":23,"name":24,"slug":25},"6b9179c3-17b2-43ff-a431-a03d6eb32d89","Vue2 生态","vue2-生态",{"id":27,"name":28,"avatar":18},"f9d0f2de-c700-4f90-b535-afd3dbe78128","Admin",[30],{"id":5,"name":6,"slug":6},{"id":32,"title":33,"slug":34,"content":35,"excerpt":33,"coverImage":36,"status":16,"isPinned":17,"pinnedAt":18,"viewCount":37,"publishedAt":38,"createdAt":38,"updatedAt":39,"category":40,"author":44,"tags":45},"3b2d8d3e-6e3a-42a7-bb0f-d8f80121993f","实现input框粘贴图片，图片上传","实现input框粘贴图片-图片上传","```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cel-input\n      v-model=\\\"imgSrc\\\"\n      type=\\\"textarea\\\"\n      :placeholder=\\\"placeholder\\\"\n      @input=\\\"setInput\\\"\n      @paste.capture.prevent=\\\"pasting\\\"\n    \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Cscript setup lang=\\\"ts\\\">\n  import axios from 'axios';\n  import { userStore } from '@\u002Fstore\u002Fmodule\u002Fuser';\n  import { ElMessage } from 'element-plus';\n  const user: any = userStore();\n  const imgSrc = ref('');\n  const emit = defineEmits(['uploaded']);\n\n  const props = defineProps({\n    placeholder: {\n      type: String,\n      default: '',\n    },\n\n    imgSrcData: {\n      type: String,\n      default: '',\n    },\n  });\n\n  watch(\n    () => props.imgSrcData,\n    (newValue, oldValue) => {\n      if (newValue !== oldValue) {\n        imgSrc.value = newValue;\n      }\n    },\n    {\n      immediate: true, \u002F\u002F立即执行\n    },\n  );\n\n  \u002F\u002F 监听粘贴事件\n  const pasting = (event: { clipboardData: { getData: (arg0: string) => any } }) => {\n    console.log(event.clipboardData);\n    let txt = event.clipboardData.getData('Text');\n    console.log('文本', txt);\n    if (typeof txt == 'string') {\n      imgSrc.value += txt;\n      emit('uploaded', imgSrc.value);\n    }\n    let file = null;\n    const items = (event.clipboardData || window.clipboardData).items;\n    console.log(items);\n    if (items.length) {\n      let canUpload = false;\n      for (let i = 0; i \u003C items.length; i++) {\n        if (items[i].type.indexOf('image') !== -1) {\n          file = items[i].getAsFile();\n          handleChange(file);\n          if (!canUpload) {\n            canUpload = !canUpload;\n          }\n          break;\n        }\n      }\n    }\n  };\n  \u002F\u002F 上传\n  const handleChange = (file: Blob) => {\n    let formData = new FormData();\n    formData.append('file', file);\n    axios\n      .post(import.meta.env.VITE_APP_UPLOAD_URL, formData, {\n        headers: {\n          'Content-type': 'multipart\u002Fform-data',\n          token: user.getToken(),\n        },\n      })\n      .then((res) => {\n        imgSrc.value = res.data.data.info.src;\n        emit('uploaded', imgSrc.value);\n        ElMessage({ message: '图片上传成功！', type: 'success' });\n      })\n      .catch((err) => {\n        ElMessage({ message: err || '图片上传失败！', type: 'warning' });\n      });\n  };\n\n  const setInput = () => {\n    emit('uploaded', imgSrc.value);\n  };\n\u003C\u002Fscript>\n\n```\n","https:\u002F\u002Fcdn.xiaolong0418.com\u002Fmyblog\u002Fimages\u002F6dbf664582b1b050b94f19b4f01d9752.png",678,"2022-09-26T14:47:23.000Z","2026-06-28T21:18:30.914Z",{"id":41,"name":42,"slug":43},"da130ba9-d4f4-49f3-aa0f-149078097ef0","JavaScript","javascript",{"id":27,"name":28,"avatar":18},[46],{"id":5,"name":6,"slug":6},{"id":48,"title":49,"slug":50,"content":51,"excerpt":52,"coverImage":53,"status":16,"isPinned":17,"pinnedAt":18,"viewCount":54,"publishedAt":55,"createdAt":55,"updatedAt":56,"category":57,"author":61,"tags":62},"5a60b315-d098-4e9b-b800-3b0abc886ed5","Compressor.js前端图片压缩","compressor-js前端图片压缩","\n## 引用方法\n\n\n### Vue3\n\n```shell\nnpm i -S compressorjs\n```\n\n```shell\nimport Compressor from 'compressorjs';\n```\n\n## 使用方法\n\n```js\nimport axios from 'axios';\nimport Compressor from 'compressorjs';\n\ndocument.getElementById('file').addEventListener('change', (e) => {\n  const file = e.target.files[0];\n\n  if (!file) {\n    return;\n  }\n\n  new Compressor(file, {\n    quality: 0.6,\n    success(result) {\n      const formData = new FormData();\n      formData.append('file', result, result.name);\n      axios.post('\u002Fpath\u002Fto\u002Fupload', formData).then(() => {\n        console.log('Upload success');\n      });\n    },\n    error(err) {\n      console.log(err.message);\n    },\n  });\n  \n});\n\n```\n\n\n## 常见问题\n","JavaScript 图像压缩器","https:\u002F\u002Fcdn.xiaolong0418.com\u002Fmyblog\u002Fimages\u002Fe3ee16fcc524cdacfb6633eaa6f90d83.png",1017,"2022-08-01T02:40:13.000Z","2026-06-28T21:18:17.961Z",{"id":58,"name":59,"slug":60},"e0f3b8d8-cfe7-41fb-802b-a79699d95968","JavaScript插件","javascript插件",{"id":27,"name":28,"avatar":18},[63],{"id":5,"name":6,"slug":6},3,1,10]