我有一个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);
}
仍然没有运气。
这怎么可能?
答案 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 },
]