VueJS 2 — Повторно используемый родительский компонент, который может принимать разные дочерние элементы

#vuejs2 #components

#vuejs2 #Компоненты

Вопрос:

У меня есть родительский компонент SearchComponent:

 <template>
    
        <div>
            <div class="relative pl-8 pr-10 rounded bg-white border focus-within:bg-white focus-within:ring-1">
    
                <input v-focus @keyup.escape="clearSearch" @keyup="doSearch" v-model="searchTerm"
                       class="w-full ml-4 h-12 pl-1 text-gray-700 text-lg rounded-full border-0 bg-transparent focus:outline-none placeholder-gray-400"
                       placeholder="Search..." autocomplete="off">
    
    
            </div>
    
            <ul class="bg-white mt-4">
    
                <quick-search-item v-for="item in searchResults" :key="item.id" :item-data="item.itemData">
    
                </quick-search-item>
    
            </ul>
    
        </div>
    
    </template>
 

Он отвечает за получение пользовательского ввода и получение результатов от вызова ajax, обработку ошибок и т. Д. И генерацию списка результатов.

Что я хотел бы сделать, так это сделать это универсальным, чтобы вместо дочернего компонента с быстрым поиском я мог передавать разные типы дочерних компонентов (например, car-search-item, person-search-item и т. Д.) В зависимости от контекста, в котором пользователь находится вприложение и то, что они ищут

Я прочитал несколько руководств и не смог найти то, что пытаюсь сделать. Это может означать, что я неправильно подхожу к этому, но если кто-нибудь может указать мне правильное направление или имеет лучший подход, я был бы очень благодарен.

Спасибо, Ленни.

Ответ №1:

Я бы попытался использовать <slot> элемент. Ознакомьтесь с документацией здесь

 <parent-component>
  <slot></slot>
</parent-component>
 

Надеюсь, это поможет вам на правильном пути.

Ответ №2:

Шальк Преториус был совершенно прав: ответом на это являются слоты, в частности, слоты с ограниченной областью действия. Я нашел документы Vue немного запутанными, поскольку они относятся к получению данных из дочернего компонента, и я хотел сделать это наоборот, поэтому в качестве памятной записки для себя и чтобы помочь кому-либо еще, вот что я сделал:

В моем родительском компоненте я определил слот следующим образом:

 <slot name="results" v-bind:items="searchResults">

</slot>
 

V-привязка привязывает результаты поиска (элемент данных в родительском компоненте) к значению «элементы». затем «элементы» становятся доступными в слоте.

В моем дочернем компоненте у меня есть простая настройка свойств под названием items:

 props: {
        items: {type: Array},
    }, 
 

Затем, чтобы соединить все это вместе в моем блейд-файле, я сделал это:

 <search-component endpoint="{{ route('quick_search.index') }}">

        <template v-slot:results="props">
            <food-results :items="props.items">

            </food-results>
        </template>


 </search-component>
 

Это создает компонент поиска. Внутри этого — поскольку я использую именованные слоты — нам нужен шаблон, и мы используем v-slot, чтобы указать ему, какой слот использовать (результаты), тогда =»props» предоставляет все свойства, которые мы определили для этого слота (в данном случае только одно, ‘items’).).

Внутри шаблона мы помещаем наш дочерний компонент, а затем мы можем привязывать элементы к props.items, которые будут результатами поиска в нашем родительском компоненте.

Я рад, что это работает, и теперь я могу создавать множество различных компонентов результатов при повторном использовании компонента поиска — и, по крайней мере, я кое-что узнал сегодня!

Приветствия, Ленни.