【发布时间】:2019-06-20 22:21:34
【问题描述】:
TL;TR
我该怎么做:
getMyComponent(selectedMyComponentID).complexOperation()
对我来说,这听起来像是一件微不足道而有用的事情,例如从下拉菜单中。
更多细节
假设我正在制作某种类型的编辑器(想想 todo-list 什么的)。 GUI 具有“选定”元素的概念。 (在我们的实际案例中,它是当前可见的bootstrap nav-tab),并且我想要具有对所选元素执行不同操作的菜单项的下拉菜单。
假设我有“选定”组件的 id,获取对具有与该 id 对应的 complexOperation() 方法的 MyComponent 的引用非常困难。
也许那是因为我没有这样做“Vue 方式”。
我看到了这些方法来完成complexOperationOnSelectedMyComponent():
- 使用refs - 看起来又乱又丑
- 将MyComponent中的
complexOperation()重构为一个新的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 中也有等效的按钮。他们只是在 MyComponent 定义中调用 complexOperation() 方法。
我认为按钮是在组件内部还是外部是一个小细节。获取对所选 id 的 MyComponent 的引用,并在菜单项的 @click 处理程序中调用 selectedComponent.complexOperation()。
在我们的真实场景中,用户通过点击导航栏(不是在 MyComponent 实例上)选择“组件”,所以我们拥有的是一个 id(mydata[n].id 或上面的 0、1 或 2) .
使用 ref-s
我能做的就是将ref="components" 放入<MyComponents> 定义中。因为它在v-for 循环中,所以this.$refs.components 将是MyComponents 的数组。找到具有正确 id 的那个并使用它。
因为无法保证this.$refs.components 中的顺序,我每次都必须在数组中搜索 selectedMyComponentID,但是嘿...
这真的是最好的解决方案吗?
【问题讨论】:
-
你可以绑定一个动态的ref并使用选中的组件的id,比如
:ref="'mycomponents' + elem.id" -
谢谢,这比我的
ref="components"解决方案效果更好,即使this.$refs.mycomponents1仍然是一个包含单个元素的数组。