web-dev-qa-db-ja.com

v-modelを使用したVue.jsカスタム選択コンポーネント

Vue.jsでカスタム選択コンポーネントを作成したいと思います。特定のオプションのスタイル設定が必要なため、実際のhtmlselectのように見えて動作するdivなどで作成された「select」を作成する必要があります。

現在、私はこのようなものを持っています:

Vue.component('child', {
  template: `<div class="component-container"  @click="showOptions = !showOptions">
        <div class="component__select">
            <span class="component__select--name">Select Fruit</span>
            
            <span class="c-arrow-down" v-if="!showOptions"></span>
            <span class="c-arrow-up" v-if="showOptions"></span>
        </div>
        <ul class="component__select-options" v-if="showOptions" >
            <li class="select--option" v-for="option in options">
                <label> <input type="checkbox" :value="option"/> {{option.name}}</label>
            </li>
        </ul>
    </div>`,

  methods: {
    selectOption(option) {
      this.$emit('option', option)
    }
  },
  data: () => ({
  showOptions: false,
  }),
  props: ['options']
});

var vm = new Vue({
  el: '#app',
  data: () => ({
        options: [
  {id: 0, name: 'Apple'},
  {id: 1, name: 'Banana'},
  {id: 2, name: 'Orange'},
  {id: 2, name: 'Strawberry'},
  ],
  selectedFruit: ''
  }),
})
 .component__select {
   height: 38px;
   background-color: #F5F7FA;
   border: 1px solid #dddddd;
   line-height: 38px;
   display: grid;
   max-width: 500px;
   grid-template-columns: 10fr 1fr;
 }

 .component__select--name {
   font-size: 0.8rem;
   padding: 0 0 0 25px;
   cursor: pointer;
 }

 .c-arrow-down {
   justify-self: end;
 }

 .component__select-options {
   max-height: 180px;
   border: 1px solid #dddddd;
   border-top: none;
   overflow: auto;
   position: absolute;
   z-index: 1500;
   max-width: 500px;
   width: 500px;
   margin: 0;
   padding: 0;
 }

 .select--option {
   height: 35px;
   display: grid;
   align-content: center;
   padding: 0 0 0 25px;
   background-color: #f5f5fa;
   border-bottom: 1px solid #dddddd;
 }

 .select--option:last-child {
   border-bottom: none;
 }

 .select--option:nth-child(2n) {
   background-color: #ffffff;
 }
 
 .select--option input{
   display: none;
 }

 .single-option {
   height: 55px;
   background-color: #2595ec;
   font-size: 0.8rem;
   border: 1px solid red;
 }

 .cust-sel {
   width: 200px;
   height: 38px;
   background-color: #f5f5fa;
   border: 1px solid #dddddd;
 }

 .cust-sel:focus {
   outline-width: 0;
 }
<html>
<head>
  <title>An example</title>
</head>
<body>
  <div id="app">
    <span> This is parent component</span>
    <p>I want to have data from select here:  "{{selectedFruit}}"</p>
    <child :options="options" v-model="selectedFruit"></child>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</body>
</html>

しかし、私の問題は、子コンポーネントでv-modelを使用して、子から親コンポーネントにデータを返す方法です。

(子コンポーネントからデータを出力できることはわかっています。
<custom-select :options="someOptions" @selected="setSelectedOption"/>
しかし、再利用可能である必要があり、親コンポーネントのすべての選択からデータを取得するためのメソッドをますます作成することは、正確に機能するはずではないと思います。)

また、IDだけでなく、オブジェクト全体を返す必要があります。 (それが私が:value="option"を持っている理由です)何かアイデアはありますか?

3
ineffable

カスタムコンポーネントでv-modelを使用する場合、必要なのは「value」という名前の小道具を宣言することだけです。コンポーネントが必要な場合は、「input」イベントを発行します。

このようなもの:

<template>
  <form @submit.prevent="$emit('onSearch',val)" class="form-perfil">
    <div class="form-group col-md-12">
      <input v-model="val" @input="$emit('input',val)" 
      placeholder="filtrar resultados" class="form-control">
    </div>
  </form>
</template>
<script>
module.exports = {
  name: "CaixaFiltro",
  props: ["value"],
  data: _ => ({ val: "" }),
  created() {
    this.val = this.value
  }
}
</script>

次に、(コンポーネントを登録した後)次のように使用できます。

<caixa-filtro v-model="textoBusca" @onSearch="listar"></caixa-filtro>

あなたはより詳細な情報を見つけることができます そこに

0
Sombriks