TL; TR
Как мне:
getMyComponent(selectedMyComponentID).complexOperation()
Для меня это звучит как тривиальная и полезная вещь, например, из выпадающего меню.
Aнемного подробнее
Предположим, я делаю какой-то редактор (например, список задач или что-то в этом роде).GUI имеет концепцию «выбранного» элемента.(В нашем реальном случае это видимая загрузочная навигационная вкладка ), и я хочу иметь выпадающие меню с пунктами меню, которые выполняют различные операции с выбранным элементом.
Предполагая, что у меня есть идентификатор «выбранного» компонента, получить ссылку на MyComponent, который имеет метод complexOperation()
, соответствующий этому идентификатору, на удивление сложно.
Возможно, это потому, что я этого не делаю "путь Vue ".
Я вижу эти способы достижения complexOperationOnSelectedMyComponent()
:
- использование ref s - кажется грязным и безобразным
- Реорганизовать
complexOperation()
из MyComponent в новый MyData, чтобы бизнес-логика данных использовалась приложениями App.vue и MyComponent.vue.Теперь родитель меняет данные и, следовательно, подпирает - звучит vue-ish.Но это приводит к большому количеству шаблонов, поскольку каждая операция в каждом компоненте теперь имеет две версии.Я не фанат шаблонов и дублирования ... - использовать vuex?Я думаю, что я еще не там ...
- Использовать экземпляр Vue "шины событий" и события $ emit от родителя к потомку.Кажется излишним.И это грязно и имеет шаблон.
Я что-то упустил?Разве это не довольно стандартный материал?
Детали
Для простоты мы скажем, что есть шаблон:
<template>
<div id="app">
<div v-for="elem in mydata" :key="elem.id" @click="setSelected(elem)">
<MyComponent :value="elem"/>
</div>
<button @click="complexOperationOnSelectedComponent">
Complex operation on Selected Component
</button>
</div>
</template>
и структура данных, где первыйизначально выбран один:
data() {
return {
mydata: [
{ id: 0, foo: "bar", selected: true },
{ id: 1, foo: "baz", selected: false },
{ id: 2, foo: "world", selected: false }
]
};
}
(Завершено codesandbox )
Итак, есть кнопка «Сложная операция с выбранным компонентом».Но что я должен добавить в метод complexOperationOnSelectedComponent
?
Приведенные выше коды и поле также имеют эквивалентные кнопки внутри каждого компонента MyComponent.Они просто вызывают метод complexOperation()
в определении MyComponent.
Я думаю, что кнопка находится внутри или снаружи компонента, является второстепенной деталью.Получите ссылку на MyComponent для выбранного идентификатора и вызовите selectedComponent.complexOperation()
в обработчике @click
пункта меню.
В нашем реальном сценарии пользователь выбирает «компонент», нажимая на навигационную панель,(не в экземпляре MyComponent), поэтому у нас есть идентификатор (mydata[n].id
или 0, 1 или 2 выше).
Использование ref-s
То, что я мог сделать, это поставитьref="components"
в определении <MyComponents>
.Поскольку он находится в цикле v-for
, this.$refs.components
будет массивом MyComponents
.Найдите тот с правильным идентификатором и используйте его.
Поскольку нет никакой гарантии относительно порядка в this.$refs.components
Мне бы пришлось каждый раз искать в массиве selectedMyComponentID, но эй ...
Это действительно лучшее решение?