Erstellen einer Steuerungskomponente für Listentastaturen mit Vue.js und bereichsbezogenen Slots

Es gibt großartige Pakete, mit denen Sie eine Dropdown-Liste erstellen und mit der Tastatur steuern können. Aber was ist, wenn Sie dafür kein Paket verwenden können und eine benutzerdefinierte Komponente mit dieser Art von Funktionalität von Grund auf neu implementieren müssen? Glücklicherweise ist es mit Vue sehr einfach, dies zu implementieren, und in diesem Tutorial werden wir die Scoped-Slot-Funktion von Vue verwenden.

Lassen Sie uns zunächst ein einfaches Projekt-Setup erstellen. Wir werden Vue-Cli 3 verwenden, das jetzt eine stabile Version hat. Weitere Informationen dazu finden Sie unter Öffnen Sie das Terminal und installieren Sie vue-cli 3, falls Sie es noch nicht haben:

npm install -g @vue/cli

or

yarn global add @vue/cli

Erstellen Sie nach der Installation ein neues Projekt, indem Sie diesen Befehl im Terminal ausführen

vue create vue-list-keyboard-control

Sie können das Standard-Setup verwenden oder zusätzliche Funktionen manuell auswählen, wenn Sie möchten, aber wir werden sie nicht benötigen. Nachdem das Projekt erstellt wurde, wechseln Sie in das Projektverzeichnis und starten Sie den Server:

cd vue-list-keyboard-control && npm run serve

Ändern Sie nun die App.vue-Datei so, dass sie wie folgt aussieht:

<template>
  <div id="app">
  </div>
</template>

<script>
export default {
  name: "app",
  components: {}
};
</script>

<style lang="scss">
</style>

Wir möchten eine klare Vorlage ohne anfängliche Ergänzung haben. Jetzt brauchen wir natürlich eine Liste, die wir mit einer Tastatur steuern. Erstellten Hook in der Datei App.vue hinzufügen und dort eine neue Liste erstellen. Außerdem müssen wir die Liste anzeigen und werden auch ein wenig Styling hinzufügen. So sollte Ihre Datei aussehen

<template>
  <div id="app">
  	<!-- Here we loop through the list and display the item -->
    <div
      v-for="(item, index) in $options.list" 
      class="list-item"
      :key="index">
      <p>{{item}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "app",
  components: {},
  created() {
  	// Array with some items to create a list
    this.$options.list = ["hello", "world", "this", "is", "a", "list"];
  }
};
</script>

<style lang="scss">
#app {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  height: 100vh;
}
.list-item {
  width: 150px;
  text-align: center;
  border: 1px solid #999;
  cursor: pointer;
}
.list-item {
  width: 150px;
  text-align: center;
  border: 1px solid #999;
  cursor: pointer;
}

.list-item:hover,
.list-item.selected {
  background-color: yellowgreen;
}
</style>

Wenn Sie die App.vue-Datei speichern, sollten Sie einen Bildschirm wie diesen sehen:

initial.png

Wir haben also eine Liste, aber jetzt müssen wir Funktionen hinzufügen, um sie mit einer Tastatur zu steuern. Erstellen Sie eine neue Datei im Ordner „Komponenten“ mit dem Namen „WithKeyboardControl.vue“. Wir müssen hier Daten, Rendering, Methoden, erstellte und zerstörte Eigenschaften der Vue-Instanz verwenden. Wir werden den Hook „created“ verwenden, um Ereignis-Listener zu erstellen, und den Hook „destroyed“, um alle Ereignis-Listener zu entfernen. Fügen wir jedoch einfach die Eigenschaft „s selectedIndex“ zu „data“ sowie die Renderfunktion hinzu, die unsere Liste rendert, und die Eigenschaft „listLength“, da wir sie später in den Handlern benötigen.

<script>
export default {
  props: {
  	listLength: Number
  },
  data() {
    return {
      // Index of the list item to display
      // -1 means that no item is selected
      selectedIndex: -1
    };
  },
  render(h) {
  	// Create a div and render content in the scoped slot as well as pass the selectedIndex
    return h(
      "div",
      this.$scopedSlots.default({ selectedIndex: this.selectedIndex })
    );
  },
  methods: {},
  created() {},
  destroyed() {}
};
</script>

Importieren und registrieren Sie nun diese Komponente in der App.vue-Datei. Wir packen unsere Liste auch in die Komponente „with-keyboard-control“ und mit „