So implementieren Sie die @person-Funktion über Vue

So implementieren Sie die @person-Funktion über Vue

Dieser Artikel verwendet Vue und fügt Mausklickereignisse und einige kleine Seitenoptimierungen hinzu

Grundstruktur

Erstellen Sie eine sandBox.vue-Datei, um die Grundstruktur der Funktion zu schreiben

 <div Klasse="Inhalt">
    <!--Textfeld-->
    <div
      Klasse="Herausgeber"
      ref="divRef"
      Inhalt editierbar
      @keyup="handkeKeyUp"
      @keydown="Tastennachunten bedienen"
    ></div>
    <!--Optionen-->
    <AtDialog
      v-if="Dialog anzeigen"
      :sichtbar="Dialog anzeigen"
      :position="Position"
      :Abfragezeichenfolge="Abfragezeichenfolge"
      @onPickUser="Benutzer auswählen"
      @onHide="handleHide"
      @onShow="Anzeigengriff"
    ></AtDialog>
  </div>
<Skript>
importiere AtDialog aus '../components/AtDialog'
Standard exportieren {
  Name: 'sandBox',
  Komponenten: { AtDialog },
  Daten () {
    zurückkehren {
      node: '', // Den Knoten abrufen user: '', // Den Inhalt des ausgewählten Elements endIndex: '', // Die letzte Cursorposition queryString: '', // Suchwert showDialog: false, // Ob das Popup-Fenster angezeigt werden soll position: {
        x: 0,
        j: 0
      }//Anzeigeposition des Popup-Fensters}
  },
  Methoden: {
    // Cursorposition abrufen getCursorIndex () {
      const Auswahl = Fenster.getSelection()
      return selection.focusOffset //Wählen Sie den Offset von focusNode am Anfang},
    //Knoten abrufen getRangeNode () {
      const Auswahl = Fenster.getSelection()
      return selection.focusNode // ausgewählter Endknoten},
    // Die Stelle, an der das Popup-Fenster erscheint getRangeRect () {
      const Auswahl = Fenster.getSelection()
      const range = selection.getRangeAt(0) // ist ein generisches Objekt zum Verwalten von Auswahlbereichen const rect = range.getClientRects()[0] // Wähle einen Text aus und erhalte den Bereich des ausgewählten Textes const LINE_HEIGHT = 30
      zurückkehren {
        x: Rechteck.x,
        y: Rechteck.y + Zeilenhöhe
      }
    },
    // Ob @ angezeigt werden soll
    zeigeAt() {
      const node = this.getRangeNode()
      wenn (!node || node.nodeType !== Node.TEXT_NODE) ​​​​false zurückgeben
      const Inhalt = node.textContent || ''
      const regx = /@([^@\s]*)$/
      const match = regx.exec(content.slice(0, this.getCursorIndex()))
      Rückgabewert: Übereinstimmung und Übereinstimmungslänge === 2
    },
    // Holen Sie sich @user getAtUser () {
      const content = this.getRangeNode().textContent || ''
      const regx = /@([^@\s]*)$/
      const match = regx.exec(content.slice(0, this.getCursorIndex()))
      wenn (Match && Matchlänge === 2) {
        Rückspiel[1]
      }
      Rückgabe undefiniert
    },
    // Erstelle ein Label createAtButton (Benutzer) {
      const btn = document.createElement('span')
      btn.style.display = "Inline-Block"
      btn.dataset.user = JSON.stringify(Benutzer)
      btn.className = "at-Schaltfläche"
      btn.contentEditable = "falsch"
      btn.textContent = `@${Benutzername}`
      const Wrapper = Dokument.createElement('span')
      wrapper.style.display = "Inline-Block"
      wrapper.contentEditable = "false"
      const spaceElem = document.createElement('span')
      spaceElem.style.whiteSpace = "vor"
      spaceElem.textContent = "\u200b"
      spaceElem.contentEditable = "false"
      const clonedSpaceElem = spaceElem.cloneNode(true)
      Wrapper.AnhängenUntergeordnetesElement(spaceElem)
      Wrapper.AnhängenKind(btn)
      Wrapper.appendChild(geklontesSpaceElem)
      Rücksendeverpackung
    },
    replaceString (roh, Ersetzer) {
      returniere raw.replace(/@([^@\s]*)$/, Ersetzer)
    },
    // Füge @tag replaceAtUser (Benutzer) { ein.
      const node = dieser.knoten
      if (Knoten && Benutzer) {
        const Inhalt = node.textContent || ''
        const endIndex = this.endIndex
        const preSlice = this.replaceString(content.slice(0, endIndex), '')
        const restSlice = content.slice(endIndex)
        const parentNode = node.parentNode
        const nextNode = node.nextSibling
        const vorherigerTextNode = neuer Text(preSlice)
        const nextTextNode = neuer Text('\u200b' + restSlice) // 0 breite Zeichen hinzufügen const atButton = this.createAtButton(Benutzer)
        übergeordneter Knoten.entfernenUntergeordnetesElement(Knoten)
        // In das Textfeld einfügen if (nextNode) {
          parentNode.insertBefore(vorherigerTextNode, nächsterNode)
          parentNode.insertBefore(atButton, nächsterNode)
          parentNode.insertBefore(nächsterTextNode, nächsterNode)
        } anders {
          übergeordneter Knoten.anhängendesKind(vorherigerTextknoten)
          parentNode.anhängenKind(atButton)
          parentNode.appendChild(nächsterTextNode)
        }
        // Cursorposition zurücksetzen const range = new Range()
        const Auswahl = Fenster.getSelection()
        range.setStart(nächsterTextNode, 0)
        range.setEnd(nächsterTextNode, 0)
        Auswahl.AlleBereicheentfernen()
        Auswahl.addRange(Bereich)
      }
    },
    //Tastatur hoch eventhandkeKeyUp () {
      wenn (this.showAt()) {
        const node = this.getRangeNode()
        const endIndex = this.getCursorIndex()
        dieser.Knoten = Knoten
        dies.endIndex = endIndex
        diese.position = diese.getRangeRect()
        this.queryString = this.getAtUser() || ''
        this.showDialog = true
      } anders {
        this.showDialog = false
      }
    },
    //Tastaturkürzel handleKeyDown (e) {
      wenn (dieser.showDialog) {
        wenn (e.code === 'PfeilNachOben' ||
          e.code === 'Pfeil nach unten' ||
          e.code === 'Eingeben') {
          e.preventDefault()
        }
      }
    },
    // Verstecke das Auswahlfeld nach dem Einfügen des Tags handlePickUser (user) {
      this.replaceAtUser(Benutzer)
      this.user = Benutzer
      this.showDialog = false
    },
    //Auswahlfeld ausblenden handleHide () {
      this.showDialog = false
    },
    //Zeige das Auswahlfeld handleShow () {
      this.showDialog = true
    }
  }
}
</Skript>
 
<style scoped lang="scss">
  .Inhalt {
    Schriftfamilie: serifenlos;
    h1{
      Textausrichtung: zentriert;
    }
  }
  .Editor {
    Rand: 0 automatisch;
    Breite: 600px;
    Höhe: 150px;
    Hintergrund: #fff;
    Rand: 1px durchgehend blau;
    Rahmenradius: 5px;
    Textausrichtung: links;
    Polsterung: 10px;
    Überlauf: automatisch;
    Zeilenhöhe: 30px;
    &:Fokus {
      Gliederung: keine;
    }
  }
</Stil>

Wenn ein Klickereignis hinzugefügt wird, müssen die Knoten- und Cursorposition im [Keyboard Up Event] ermittelt und in den Daten gespeichert werden

 //Tastatur hoch eventhandkeKeyUp () {
      wenn (this.showAt()) {
        const node = this.getRangeNode() // Den Knoten abrufen const endIndex = this.getCursorIndex() // Die Cursorposition abrufen this.node = node 
        dies.endIndex = endIndex 
        diese.position = diese.getRangeRect()
        this.queryString = this.getAtUser() || ''
        this.showDialog = true
      } anders {
        this.showDialog = false
      }
    },

Erstellen Sie eine neue Komponente und bearbeiten Sie die Popup-Optionen 

<Vorlage>
<div
  Klasse="Wrapper"
  :style="{position:'fest',oben:position.y +'px',links:position.x+'px'}">
  <div v-if="!mockList.length" class="empty">Keine Suchergebnisse</div>
  <div
    v-für="(Element,i) in MockList"
    :Schlüssel="Artikel-ID"
    Klasse="Artikel"
    :Klasse="{'aktiv': i === index}"
    ref="BenutzerRef"
    @click="klickenBei($event,item)"
    @mouseenter="hoverAt(i)"
  >
    <div Klasse="name">{{item.name}}</div>
  </div>
</div>
</Vorlage>
 
<Skript>
const mockData = [
  { Name: 'HTML', ID: 'HTML' },
  { Name: "CSS", ID: "CSS" },
  { Name: 'Java', ID: 'Java' },
  { Name: 'JavaScript', ID: 'JavaScript' }
]
Standard exportieren {
  Name: "AtDialog",
  Requisiten: {
    sichtbar: Boolean,
    Position: Objekt,
    queryString: Zeichenfolge
  },
  Daten () {
    zurückkehren {
      Benutzer: [],
      Index: -1,
      mockList: mockData
    }
  },
  betrachten:
    Abfragezeichenfolge (Wert) {
      Wert? this.mockList = mockData.filter(({ name }) => name.startsWith(val)) : this.mockList = mockData.slice(0)
    }
  },
  montiert () {
    document.addEventListener('keyup', dieser.keyDownHandler)
  },
  zerstört () {
    document.removeEventListener('keyup', this.keyDownHandler)
  },
  Methoden: {
    keyDownHandler (e) {
      wenn (e.code === 'Escape') {
        dies.$emit('onHide')
        zurückkehren
      }
      //Tastatur gedrückt => ↓
      wenn (e.code === 'PfeilNachUnten') {
        wenn (dieser.index >= diese.mockList.length - 1) {
          dieser.index = 0
        } anders {
          dieser.index = dieser.index + 1
        }
      }
      //Tastatur gedrückt => ↑
      wenn (e.code === 'PfeilNachOben') {
        wenn (dieser.index <= 0) {
          dieser.index = diese.mockList.length - 1
        } anders {
          dieser.index = dieser.index - 1
        }
      }
      //Tastatur gedrückt => Enterif (e.code === 'Enter') {
        wenn (diese.mockList.length) {
          const Benutzer = {
            Name: diese.mockList[dieser.index].name,
            ID: diese.mockList[diesen.index].id
          }
          dies.$emit('onPickUser', Benutzer)
          dieser.index = -1
        }
      }
    },
    clickAt (e, Artikel) {
      const Benutzer = {
        Name: Artikelname,
        ID: Artikel-ID
      }
      dies.$emit('onPickUser', Benutzer)
      dieser.index = -1
    },
    hoverAt (Index) {
      dieser.index = index
    }
  }
}
</Skript>
 
<style scoped lang="scss">
  .wrapper {
    Breite: 238px;
    Rand: 1px durchgezogen #e4e7ed;
    Rahmenradius: 4px;
    Hintergrundfarbe: #fff;
    Kastenschatten: 0 2px 12px 0 RGB (0 0 0 / 10 %);
    Box-Größe: Rahmenbox;
    Polsterung: 6px 0;
  }
  .leer{
    Schriftgröße: 14px;
    Polsterung: 0 20px;
    Farbe: #999;
  }
  .Artikel {
    Schriftgröße: 14px;
    Polsterung: 0 20px;
    Zeilenhöhe: 34px;
    Cursor: Zeiger;
    Farbe: #606266;
    &.aktiv {
      Hintergrund: #f5f7fa;
      Farbe: blau;
      .Ausweis {
        Farbe: blau;
      }
    }
    &:erstes-Kind {
      Rahmenradius: 5px 5px 0 0;
    }
    &:letztes-Kind {
      Rahmenradius: 0 0 5px 5px;
    }
    .Ausweis {
      Schriftgröße: 12px;
      Farbe: rgb(83, 81, 81);
    }
  }
</Stil>

Oben finden Sie Einzelheiten zur Implementierung der @人-Funktion über Vue. Weitere Informationen zur Vue @人-Funktion finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Verwenden Sie vue3, um ein Mensch-Katze-Kommunikations-Applet zu implementieren
  • Realisierung der intelligenten Roboter-Antwortfunktion von Vue+AI
  • Vue.js implementiert h5-Roboter-Chat (Betaversion)
  • Vue+tracking.js implementiert die Gesichtserkennungsfunktion im Front-End
  • Mehrpersonen-Online-Chatroom basierend auf Vue und WebSocket
  • Eine Single-Page-Anwendungsfunktion, die mobiles QQ basierend auf Vue2 imitiert (Zugriff auf Chatbot)

<<:  Bootstrap 3.0 Studiennotizen CSS-bezogene Ergänzung

>>:  Tutorial zur Samba-Konfiguration für die Dateifreigabe im Linux-System

Artikel empfehlen

JavaScript zur Implementierung eines einfachen Web-Rechners

Hintergrund Da ich einem neuen Projektteam zugewi...

Eine kurze Einführung in die Gesamtstruktur von Tomcat

Tomcat ist weithin als Webcontainer bekannt. Es h...

Eine kurze Diskussion über die Typen von node.js-Middleware

Inhaltsverzeichnis Überblick 1. Middleware auf An...

Einführung in Docker-Container

1. Übersicht 1.1 Grundlegende Konzepte: Docker is...

Detaillierte Erläuterung des Vue Router Routing Guard

Inhaltsverzeichnis 1. Global vor jedem 1. Global ...

Dieser Artikel zeigt Ihnen, wie Sie CSS wie JS-Module importieren

Inhaltsverzeichnis Vorwort Was sind erstellbare S...

So lassen sich Python-Skripte direkt unter Ubuntu ausführen

Nehmen wir als Beispiel das Übersetzungsprogramm....

Grundlegende Schritte zur Sicherheitseinstellung für den CentOS7-Server

Schalten Sie den Ping-Scan aus, obwohl dies nicht...

Detailliertes Tutorial zur Installation von CUDA9.0 auf Ubuntu16.04

Vorwort: Dieser Artikel basiert auf den Erfahrung...

So verwenden Sie React zur Implementierung einer Bilderkennungs-App

Lassen Sie mich Ihnen zuerst das Effektbild zeige...