Vue Router 正确处理 v-html 指令内部存在的链接

问题描述 投票:0回答:2

我正在使用 Vue 3(不带 TS)和 Vue Router 4。

我从 API 中获得了一些降价信息,我使用

markdown-it
对其进行解析,然后通过
v-html
指令将其提供给组件。解析本身工作正常,一切都按其应有的方式显示,但是如果我有一个
<a>
标签指向应用程序内部的路径,那么它显然没有被作为正确的
<router-link>
处理,因此它会强制页面刷新,我显然想避免这种情况。

有没有办法让我处理内部链接并让

v-html
通过
router-link
渲染它,以便它能够正确导航?

我的组件非常简单

<template>
  <div>
    <h1>{{ title }}</h1>
    <span v-html="content"></span>
  </div>
</template>

<script>
  import { parseMarkdown } from "../../helpers/markdownParser";

  export default {
    name: "BlogPost",
    data() {
      return {
        slug: undefined,
        title: null,
        content: null,
      };
    },
    async beforeCreate() {
      this.slug = this.$route.params.slug;

      await this.$axios.get(`/posts/${this.slug}`).then((response) => {
        const data = response.data[0];

        this.title = data.title;
        this.content = parseMarkdown(data.content);
      });
    },
  };
</script>

parseMarkdown
辅助方法只需调用
markdown-it
并将解析后的标记作为字符串返回。

markdownParser.js

import MarkdownIt from "markdown-it";

export const parseMarkdown = (html) => {
  return markdown.render(html);
};

或者,除了

v-html
之外,还有其他方法可以将解析后的 Markdown 放到页面上吗?

编辑:澄清我从

parseMarkdown()
得到的信息。

降价示例:

# Example File

This is an **example** of what `markdown-it` does with the file.

[Links work](https://example.com), too. Though [internal links](/example) don't work quite as expected.

    ```html
    <p>We can also have codeblocks in our markdown</p>
    ```

markdown-it
回馈什么

<h1>Example File</h1>

<p>This is an <strong>example</strong> of what <code>markdown-it</code> does with the file.</p>

<p><a href="https://example.com">Links work</a>, too. Though <a href="/example">internal links</a> don't work quite as expected.</p>

<pre><code class="lang-html">
  &lt;p&gt;
    We can also have codeblocks in our markdown
  &lt;/p&gt;
</code></pre>
javascript vue.js vue-router vuejs3
2个回答
1
投票

我在 Vue 应用程序外部显示 HTML 创建并从 API 下载时遇到了同样的问题。

所以我在HTML容器DIV上添加了点击事件:

<div v-html="body" @click.prevent="click"></div>

然后添加了一个方法来检查单击是否在 A 标签上,然后将路径推送到路由器上。

methods: {
    click(ev) {
        if (ev.target.tagName === "A") {
            this.$router.push(new URL(ev.target.href).pathname);
        }
    },
},

可能不是最优雅的解决方案,但它很简单,对我有用,并且不需要其他 npm 包。


0
投票

感谢这个答案:https://stackoverflow.com/a/51033863/275801

<template>
  <component :is="message" />
</template>

<script setup lang="tsx">
const message = <div>Visit the <router-link to="/about">About</router-link> page to learn more.</div>;
</script>

我的示例使用 tsx,但你可以将其更改为 jsx。如果您不使用 jsx 或 tsx,您可能可以使用 h 函数 创建 vnode(我没有对此进行测试)。

© www.soinside.com 2019 - 2024. All rights reserved.