来自服务器数据的Vue2路由器链接

时间:2017-11-09 10:31:23

标签: javascript vue.js vuejs2 frontend single-page-application

我有一个Vue2 SPA页面,它正在从服务器加载内容。 它可以由CMS中的客户编辑。

当用户添加相对链接(让我们说/ about-us)时,应该由Vue选择并将其视为菜单链接(已经/ about-us链接)。

然而,在内容中添加的链接到/ about-us正在重新加载整个页面,因此它不会被选为vue路由。

如何将路由器连接到此类链接?

到目前为止我所做的是改变后端响应中的内容。

所以我基本上在改变

<a href="/about-us">Text</a>

<router-link :to="{ path: '/about-us'}">Text</router-link>

使用:

function parseVueLinks($value)
{
    $pattern = "/<a([^>]*) href=\\\"[^http|https|mailto|tel]([^\\\"]*)\"([^>]*)>(.*?)<(\\/a>)/";
    $replace = "<router-link$1 :to=\"{ path: '$2'}\">$4</router-link>";

    return preg_replace($pattern, $replace, $value);
}

仍然没有运气。

这怎么可能?

3 个答案:

答案 0 :(得分:5)

如果我理解正确你的问题不是链接解析,这看起来很好。您希望编译生成的HTML,以便Vue路由器可以启动。有一个函数Vue.compile可以帮助您:

Vue.component('my-component', {
  template: '<div></div>',
  props: {
    html: String
  },
  mounted() {
    let { render, staticRenderFns } = Vue.compile(this.html);
    new Vue({ el: this.$el, render, staticRenderFns, router })
  }
});

使用此组件,您可以使用prop html指定任何HTML,然后将在mounted事件中编译并替换组件模板。请注意router传递给new Vue(),这是对您的Vue路由器的引用,这是必需的,因此HTML中的所有<router-link>标记都可以解析。

现在您可以使用此组件来编译HTML:

<my-component :html="content"></my-component>

其中var content = parseVueLinks('<a href="/about-us">Text</a>')

您可以在此处查看一个有效的示例https://codepen.io/anon/pen/BmmjwV

答案 1 :(得分:1)

我认为您的替代正则表达式很好但缺少一个/。 实际上,在测试之后,我看到了解析的结果:

<a href="/about-us">Text</a>

输出:

<router-link :to="{ path: 'about-us'}">Text</router-link>

而不是正确:

<router-link :to="{ path: '/about-us'}">Text</router-link>

(请参阅about-us而不是/about-us

请你试试这个:

function parseVueLinks($value)
{
    $pattern = "/<a([^>]*) href=\\\"[^http|https|mailto|tel]([^\\\"]*)\"([^>]*)>(.*?)<(\\/a>)/";
    $replace = "<router-link$1 :to=\"{ path: '/$2'}\">$4</router-link>";

    return preg_replace($pattern, $replace, $value);
}

答案 2 :(得分:1)

执行此操作的最简单的正则表达式模式是/<a href="([^>]*)">(.+)<\/a>/

测试示例:

console.clear() 

const parseVueLinks = ($value) => {
  const re = /<a href="([^>]*)">(.+)<\/a>/g;
  const matches = re.exec($value);
  return `<router-link :to="{ path: '${matches[1]}'}">${matches[2]}</router-link>`
}

console.log(parseVueLinks('<a href="/about-us">Text</a>'))
console.log(parseVueLinks('<a href="http://google.com">Goooooogle</a>'))


我不知道PHP,但我猜测等效的PHP可能是(在https://www.functions-online.com/preg_match.html测试):

function parseVueLinks($value)
{
  $pattern = "/<a href="([^>]*)">(.+)<\/a>/";
  $matches = [];
  preg_match($pattern, $replace, $matches);
  return "<router-link :to=\"{ path: '" + $matches[1] + "'}\">" + $matches[2] + "</router-link>"; 
}

我想知道你的正则表达式中存在http|https|mailto|tel,这是否意味着你想对链接进行一些验证?

如果是这样,使用preg_match()允许在输出之前在$matches[1]上执行第二个正则表达式步骤。验证作为第二步而不是使用一个大正则表达式似乎更简单。

修改以下评论

  

问题不在正则表达式中。在Vue中没有解析从服务器拉出的内容

如果您使用服务器端呈现,这可能不适用,但这是我从内容应用链接的方式。

MyComponent.ts

<template>
  <div class="row">
    ...
      <router-link :to="'/' + measure.link" class="measure">
        <i class="measure-icon fa fa-lg" :class="measure.icon" aria-hidden="true">
          <span class="title">{{measure.title}}</span>
        </i>
      </router-link>

这里,measure是从服务器获取的对象。我正在提取完整的<router-link>,这可能与Dynamic Component一起使用,但似乎有点矫枉过正,因为 知道 元素将是<router-link

请注意,如果服务器响应 404 还存在问题,您可以通过在链接之前添加#来使用哈希模式路由(默认),例如#/about-us

或者,在Vue路由器中设置历史记录模式。

const router = new Router({
  routes,
  mode: 'history'
})

这要求服务器重定向到index.html以获取404.请参阅HTML History Mode

此外,您需要使用全能路线处理Vue中的 404

const routes = [
  ...
  { path: '*', component: NotFoundComponent },
]