[英]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.