在 Vue 中要求 v-html 中的图像
Require image inside v-html in Vue
我正在使用 Tiptap 编辑器编写内容,然后通过 v-html
指令附加由它生成的数据。
我知道 v-html 可以处理像 'https://something/file.jpg' 这样具有绝对来源的图像,但我需要一个通过 Webpack 并在其名称中获取哈希值的图像。并且要求图像似乎在 v-html 中不起作用。有人解决过这样的问题吗?
更新
代码如下:
<div v-html="someData"></div>
someData 作为对异步请求的响应出现,看起来像这样:
<p> kjfdkf </p> <p> kfdfk </p> <div> kdfjdkf </div>
这是文本编辑器的标准输出。为了不使用标签显示它,我将它传递给 v-html
。问题是如何处理通过 webpack 的图像。我不知道。
我不确定我是否正确理解了你的问题,但考虑到你有一个像这样的 HTML 字符串:
<p> kjfdkf </p>
<img src="PATH" />
<p> kfdfk </p>
<img src="PATH" />
<div> kdfjdkf </div>
...内部有随机图像元素,您可能可以解析 HTML 以将图像元素的来源更改为其原始数据,而不是当前的相对路径。
DOMParser
似乎是解析 HTML 最简单的选项,因为您可以在一行中解析它:
let el = new DOMParser().parseFromString(this.html, "text/html");
然后找到所有图像元素:
let imgs = el.getElementsByTagName("img");
...将其来源更改为原始形式:
imgs.forEach((img) => (img.src = require(img.src)));
...select el
的正文(因为那是你的 HTML 所在的位置):
let body = el.body;
...并且return其内部HTML:
return body.innerHTML;
你可以将这一切包装在一个计算 属性:
computed: {
processedHtml() {
let el = new DOMParser().parseFromString(this.html, "text/html"),
imgs = el.getElementsByTagName("img");
imgs.forEach((img) => (img.src = require(img.src)));
let body = el.body;
return body.innerHTML;
},
}
完整代码如下:
<template>
<div id="app">
<div v-html="processedHtml"></div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
html: `<p> kjfdkf </p><img src="PATH" /> <p> kfdfk </p> <img src="PATH" /> <div> kdfjdkf </div>`,
};
},
computed: {
processedHtml() {
let el = new DOMParser().parseFromString(this.html, "text/html"),
imgs = el.getElementsByTagName("img");
imgs.forEach((img) => (img.src = require(img.src)));
let body = el.body;
return body.innerHTML;
},
},
};
</script>
或者,如果您将图像移动到您的 public
目录,它们的名称将不会被 webpack 修改,因此您可以避免这一切。
我不得不在 marsnebulasoup 的回答中添加一点
首先,当我们在 Tiptap 编辑器中保存图像源时,如果我输入 @/assets/img/someImg.jpg,它会将其保存为 'http://localhost:8080/@/assets/img/someImg.jpg',这不是我想要的。所以我添加了一行来提取图像名称:
const src = img.src.slice(img.src.lastIndexOf('/') + 1);
第二个require
不接受变量,所以我没能做到
imgs.forEach((img) => (img.src = require(img.src)));
我不得不这样做:
const imgSrc = require(`@/assets/img/${src}`);
img.src = imgSrc;
我正在使用 Tiptap 编辑器编写内容,然后通过 v-html
指令附加由它生成的数据。
我知道 v-html 可以处理像 'https://something/file.jpg' 这样具有绝对来源的图像,但我需要一个通过 Webpack 并在其名称中获取哈希值的图像。并且要求图像似乎在 v-html 中不起作用。有人解决过这样的问题吗?
更新 代码如下:
<div v-html="someData"></div>
someData 作为对异步请求的响应出现,看起来像这样:
<p> kjfdkf </p> <p> kfdfk </p> <div> kdfjdkf </div>
这是文本编辑器的标准输出。为了不使用标签显示它,我将它传递给 v-html
。问题是如何处理通过 webpack 的图像。我不知道。
我不确定我是否正确理解了你的问题,但考虑到你有一个像这样的 HTML 字符串:
<p> kjfdkf </p>
<img src="PATH" />
<p> kfdfk </p>
<img src="PATH" />
<div> kdfjdkf </div>
...内部有随机图像元素,您可能可以解析 HTML 以将图像元素的来源更改为其原始数据,而不是当前的相对路径。
DOMParser
似乎是解析 HTML 最简单的选项,因为您可以在一行中解析它:
let el = new DOMParser().parseFromString(this.html, "text/html");
然后找到所有图像元素:
let imgs = el.getElementsByTagName("img");
...将其来源更改为原始形式:
imgs.forEach((img) => (img.src = require(img.src)));
...select el
的正文(因为那是你的 HTML 所在的位置):
let body = el.body;
...并且return其内部HTML:
return body.innerHTML;
你可以将这一切包装在一个计算 属性:
computed: {
processedHtml() {
let el = new DOMParser().parseFromString(this.html, "text/html"),
imgs = el.getElementsByTagName("img");
imgs.forEach((img) => (img.src = require(img.src)));
let body = el.body;
return body.innerHTML;
},
}
完整代码如下:
<template>
<div id="app">
<div v-html="processedHtml"></div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
html: `<p> kjfdkf </p><img src="PATH" /> <p> kfdfk </p> <img src="PATH" /> <div> kdfjdkf </div>`,
};
},
computed: {
processedHtml() {
let el = new DOMParser().parseFromString(this.html, "text/html"),
imgs = el.getElementsByTagName("img");
imgs.forEach((img) => (img.src = require(img.src)));
let body = el.body;
return body.innerHTML;
},
},
};
</script>
或者,如果您将图像移动到您的 public
目录,它们的名称将不会被 webpack 修改,因此您可以避免这一切。
我不得不在 marsnebulasoup 的回答中添加一点
首先,当我们在 Tiptap 编辑器中保存图像源时,如果我输入 @/assets/img/someImg.jpg,它会将其保存为 'http://localhost:8080/@/assets/img/someImg.jpg',这不是我想要的。所以我添加了一行来提取图像名称:
const src = img.src.slice(img.src.lastIndexOf('/') + 1);
第二个require
不接受变量,所以我没能做到
imgs.forEach((img) => (img.src = require(img.src)));
我不得不这样做:
const imgSrc = require(`@/assets/img/${src}`);
img.src = imgSrc;