宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見問題
產(chǎn)品動態(tài)
精選推薦

Vue實戰(zhàn):輕松掌握輸入框@功能實現(xiàn)技巧

管理 管理 編輯 刪除

成員列表

創(chuàng)建

實現(xiàn)成員列表的方式比較簡單,其實就是一個列表,一個簡單的v-for循環(huán)就可以搞定,點擊時將當前選擇的成員項回調(diào)給父組件。

新增一個AtPop.vue文件:

<template>
  <div class="at-pop-index">
    <div v-for="(item, index) in listData" :key="index" class="at-pop-item" @click.stop="clickItem(item)">{{item.name}}</div>
  </div>
</template>
<script>
export default {
  props: {
    // 傳入需要被@的成員數(shù)組
    listData: {
      type: Array,
      default: () => []
    }
  },
  methods: {
    clickItem(item) {
      this.$emit('onSelect', item); // 調(diào)用父組件處理成員選擇的方法,并回傳當前選擇項
    }
  }
}
</script>

使用

在父組件中,注冊并使用成員列表組件。我們需要在用戶輸入@的時候彈出成員列表,因此需要監(jiān)聽用戶的輸入,然后在用戶選擇成員后需要關(guān)閉。關(guān)鍵是獲取光標位置,這個由輸入框獲取,在父組件只需要使用即可。

// 核心代碼
...
// 選擇成員時插入數(shù)據(jù),并關(guān)閉彈窗
onSelect(item) {
    console.log('onSelect', item);
    this.$refs.inputBox.insertContent(`${item.name} `); // 有空格
    this.isshowAt = false;
},
// 輸入框輸入時回調(diào)函數(shù)
inputFunc(data, event) {
    console.log('inputFunc', data, event);
    if (event.data === '@') {
        this.isShowAt = true; // 顯示彈窗
        this.$nextTick(() => {
        let dom = document.getElementsByClassName('at-pop-index')[0]; // 獲取成員列表彈窗,需要放在nextTick中
        // 設(shè)置位置
        dom.style.position = 'fixed';
        dom.style.left = Math.floor(data.left + 10) + 'px';
        dom.style.top = Math.floor(data.top) + 'px';
        dom.style.zIndex = 9999;
        })
    } else {
        this.isShowAt = false;
    }
},
...

輸入框

輸入框需要處理光標位置的獲取、將值插入到光標的位置等,是本次功能實現(xiàn)的核心。

當輸入框聚焦時,我們會看到光標閃動,想要獲取光標的位置以便于插入數(shù)據(jù),則需要借助Selection對象。Selection表示用戶選擇的一段文本范圍或者插入數(shù)據(jù)的當前位置。既然是獲取選取范圍,那當前選擇范圍的index=0就是當前光標的位置。我們想要實現(xiàn)的效果是成員列表跟隨光標移動,因此就需要獲取光標的坐標值。

獲取光標的坐標

let range = window.getSelection().getRangeAt(0); // 獲取當前光標
let position = range.getBoundinGClientRect(); // 獲取當前光標的位置

getBoundingClientRect()方法會返回一個DOMRect矩形對象,其包含矩形區(qū)域的坐標值。將獲取到的坐標值回調(diào)給父組件的方法,顯示成員列表。

當我們在輸入框輸入@的時候,頁面會出現(xiàn)成員列表,此時輸入框還是聚焦的。但是如果我們點擊了成員列表的某一項,此時輸入框已經(jīng)失焦了,雖然我們可以獲取選擇的成員并插入,如果只是簡單的字符串追加的話,光標會在下次輸入時默認定位到開頭;或者我們需要在中間插入選擇的成員,會發(fā)現(xiàn)沒有位置可以插入。因此我們需要在失焦的時候先保存當前光標,并在插入時還原光標。

保存光標

// DivEditable.vue
// 失焦
inputBlur(event) {
    this.selection = this.saveSelection();
    this.$emit('blurFunc', event);
},
// 失焦時保存光標
saveSelection() {
    if (!window.getSelection) {
        return null;
    }
    let sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
        return sel.getRangeAt(0);
    }
},

光標暫存了,我們需要將插入成員封裝成方法,并可以給父組件調(diào)用,這樣父組件在獲取到成員信息后就可以直接調(diào)用。接下來需要使用上面已經(jīng)保存的光標位置:

插入文本

// DivEditable.vue
// 恢復(fù)光標
restoreSelection(range) {
    if (range) {
        let sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }
},
// 插入數(shù)據(jù)
insertContent(value) {
    // this.$refs.editor.focus();
    let range, node;
    this.restoreSelection(this.selection); // 還原失焦前的光標位置
    range = window.getSelection().getRangeAt(0);
    range.collapse(false); // 光標移動到最后
?
    node = range.createContextualFragment(value);
    let child = node.lastChild;
    console.log('lastChild', child);
    range.insertNode(node);
    // 將光標的起始位置設(shè)置在當前插入的元素后面
    if (child) {
        range.setEndAfter(child);
        range.setStartAfter(child);
    }
?
    let sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    this.$emit('input', this.$refs.editor.innerhtml);
},

其實到這里就基本實現(xiàn)了@功能,但是還有一個問題,當輸入框失焦時回調(diào)了父組件的blurFunc方法,導(dǎo)致成員列表關(guān)閉了,但是數(shù)據(jù)還沒有拿到。處理這種問題,有兩種思路:

  • 使用setTimeout設(shè)置定時器,延后執(zhí)行關(guān)閉成員列表操作
  • 修改取數(shù)邏輯為異步操作,等到數(shù)據(jù)拿到后才關(guān)閉成員列表

簡單點,就采用setTimeout實現(xiàn)。

// InputBox.vue
blurFunc(event) {
    // 失焦時延時關(guān)閉彈窗,避免還未拿到數(shù)據(jù)
    if (this.isShowAt) {
        setTimeout(() => {
            this.isShowAt = false;
        }, 500);
    }
},

運行結(jié)果

輸入框輸入@,在光標位置附近彈出成員列表

63561202404171648434172.png

選擇成員后,將成員信息插入到輸入框中

780b3202404171649043521.png

總結(jié)

本文介紹了實現(xiàn)輸入框@功能的方法,簡單易上手

主要使用了SelectionRange對象的相關(guān)方法,完成對光標的處理以及輸入的插入

本文實現(xiàn)的@功能,無法刪除時整體刪除。目前有兩種思路:將@xxx轉(zhuǎn)換為圖片并插入到輸入框,筆者簡單寫了demo驗證了一下,效率不高,且會有卡頓;另一種方式就是監(jiān)聽退格鍵,刪除時判斷刪除對象是否被包含著有意義的@xxx中,如果是則整體刪除,如果不是則默認的方式刪除,這種方式筆者沒有嘗試,難度比較大。

來源|編程網(wǎng) 作者:泡泡魚

請登錄后查看

CRMEB-慕白寒窗雪 最后編輯于2024-04-17 16:51:15

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認正序 回復(fù)倒序 點贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無簡介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
3378
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見問題 產(chǎn)品動態(tài) 精選推薦 首頁頭條 首頁動態(tài) 首頁推薦
取 消 確 定
回復(fù)
回復(fù)
問題:
問題自動獲取的帖子內(nèi)容,不準確時需要手動修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認打賞

微信登錄/注冊

切換手機號登錄

{{ bind_phone ? '綁定手機' : '手機登錄'}}

{{codeText}}
切換微信登錄/注冊
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服