我在我的网站上聊天,从JSON文件中读取并抓取每条消息,然后使用 Vue.js 显示它。但是,我的问题是,当用户发布链接时,它不包含在锚标记<a href=""/>
中。因此无法点击。
我看到了这个post,我认为这样的东西会起作用,但是,我不允许向网站添加任何更多依赖项。我是否有办法在不添加更多依赖项的情况下做类似的事情?
显示信息的代码。
<p v-for="msg in messages">
<em class="plebe">
<b> [ {{msg.platform.toUpperCase()}} ]
<span style="color: red" v-if="msg.isadmin">{{msg.user.toUpperCase()}}</span>
<span style="color: #afd6f8" v-else="">{{msg.user.toUpperCase()}}</span>
</b>
</em>:
{{msg.message}}
</p>
答案 0 :(得分:1)
在这种情况下,它首选编写自定义功能组件。
原因是我们需要发出一个复杂的html结构,但我们必须确保正确防范xss攻击(所以v-html + http regex不在图片中)
我们也将使用渲染函数,因为渲染函数的优点是允许生成html的javascript具有更大的自由度。
<!-- chatLine.vue -->
<script>
export default {
functional: true,
render: function (createElement, context) {
// ...
},
props: {
line: {
type: String,
required: true,
},
},
};
</script>
<style>
</style>
我们现在需要考虑如何解析实际的聊天消息,为此,我将使用一个正则表达式,分割任何长度的空格(要求我们的聊天网址被空格包围,或者他们是在行的开头或结尾。)
我现在要按以下方式编写代码:
<a>
标记,并使用正确的href属性
Vue.component('chat-line', {
functional: true,
// To compensate for the lack of an instance,
// we are now provided a 2nd context argument.
// https://vuejs.org/v2/guide/render-function.html#createElement-Arguments
render: function (createElement, context) {
const children = [];
let lastMatchEnd = 0;
// Todo, maybe use a better url regex, this one is made up from my head
const urlRegex = /https?:\/\/([a-zA-Z0-9.-]+(?:\/[a-zA-Z0-9.%:_()+=-]*)*(?:\?[a-zA-Z0-9.%:_+&/()=-]*)?(?:#[a-zA-Z0-9.%:()_+=-]*)?)/g;
const line = context.props.line;
let match;
while(match = urlRegex.exec(line)) {
if(match.index - lastMatchEnd > 0) {
children.push(line.substring(lastMatchEnd, match.index));
}
children.push(createElement('a', {
attrs:{
href: match[0],
}
}, match[1])); // Using capture group 1 instead of 0 to demonstrate that we can alter the text
lastMatchEnd = urlRegex.lastIndex;
}
if(lastMatchEnd < line.length) {
// line.length - lastMatchEnd
children.push(line.substring(lastMatchEnd, line.length));
}
return createElement('p', {class: 'chat-line'}, children)
},
// Props are optional
props: {
line: {
required: true,
type: String,
},
},
});
var app = new Vue({
el: '#app',
data: {
message: 'Hello <script>, visit me at http://stackoverflow.com! Also see http://example.com/?celebrate=true'
},
});
.chat-line {
/* Support enters in our demo, propably not needed in production */
white-space: pre;
}
<script src="https://unpkg.com/vue@2.0.1/dist/vue.js"></script>
<div id="app">
<p>Message:</p>
<textarea v-model="message" style="display: block; min-width: 100%;"></textarea>
<p>Output:</p>
<chat-line :line="message"></chat-line>
</div>
答案 1 :(得分:0)
您可以watch or write computed method
获取包含网址的变量并将其更改为html内容,然后使用v-html
在网页上显示html内容