[英]How to make links clickable in a chat
我在我的网站上有一个聊天,它从 JSON 文件中读取并抓取每条消息,然后使用Vue.js显示它。 但是,我的问题是,当用户发布链接时,它不包含在锚标记<a href=""/>
中。 因此它不可点击。
我看到了这篇文章,我认为这样的事情会起作用,但是,我不允许向该站点添加任何更多的依赖项。 有没有办法让我在不添加更多依赖项的情况下做类似的事情?
用于显示消息的代码。
<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>
在这种情况下,它更喜欢编写自定义功能组件。
原因是我们需要发出复杂的 html 结构,但我们必须确保适当地防止 xss 攻击(因此 v-html + http 正则表达式不在图片中)
我们还将使用渲染函数,因为渲染函数的优点是允许 javascript 生成 html,具有更大的自由度。
<!-- chatLine.vue -->
<script>
export default {
functional: true,
render: function (createElement, context) {
// ...
},
props: {
line: {
type: String,
required: true,
},
},
};
</script>
<style>
</style>
我们现在需要考虑如何解析实际的聊天消息,为此,我将使用一个在任意长度的空格上拆分的正则表达式(要求我们的聊天 url 用空格包围,或者它们位于行的开始或结束)。
我现在将按以下方式编写代码:
<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>
您可以watch or write computed method
并将其处理为 html 内容,然后使用v-html
在页面上显示 html 内容
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.