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"
を持っている理由です)何かアイデアはありますか?
カスタムコンポーネントで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>
あなたはより詳細な情報を見つけることができます そこに :