簡體   English   中英

如何在聊天中使鏈接可點擊

[英]How to make links clickable in a chat

我在我的網站上有一個聊天,它從 JSON 文件中讀取並抓取每條消息,然后使用Vue.js顯示它。 但是,我的問題是,當用戶發布鏈接時,它不包含在錨標記<a href=""/>中。 因此它不可點擊。

我看到了這篇文章,我認為這樣的事情會起作用,但是,我不允許向該站點添加任何更多的依賴項。 有沒有辦法讓我在不添加更多依賴項的情況下做類似的事情?

用於顯示消息的代碼。

<p v-for="msg in messages">
    <em class="plebe">
        <b>&nbsp;[ {{msg.platform.toUpperCase()}} ]&nbsp;
            <span style="color: red" v-if="msg.isadmin">{{msg.user.toUpperCase()}}</span>
            <span style="color: #afd6f8" v-else="">{{msg.user.toUpperCase()}}</span>
        </b>
    </em>:&nbsp;
    {{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 用空格包圍,或者它們位於行的開始或結束)。

我現在將按以下方式編寫代碼:

  1. 列出子組件
  2. 使用正則表達式在目標字符串中查找 url
  3. 對於找到的每個網址,請執行以下操作:
    1. 如果匹配不在開頭,則將前一個匹配/開頭的文本放在子項中
    2. 將 url 作為<a>標記放在子列表中,並帶有適當的 href 屬性
  4. 最后,如果我們還剩下字符,也將它們添加到子列表中
  5. 返回包裝在 P 元素中的列表

 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 內容

v-html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM