我目前正在尝试启动并运行一个简单的Tabs / Tab组件。 事件处理机制似乎发生了变化,因此我无法使其发挥作用。
目前的实施:
Tabs.vue
<template>
<div class="tabbed-pane">
<ul class="tab-list">
<li class="tab" v-for="tab in tabs" @click="activateTab(tab)">{{ tab.header }}</li>
</ul>
<slot></slot>
</div>
</template>
<script>
import hub from '../eventhub';
export default {
props: [],
data() {
return {
tabs: []
}
},
created() {
this.$on('tabcreated', this.registerTab)
},
methods: {
registerTab(tab) {
this.tabs.push(tab);
},
activateTab(tab) {
}
}
}
</script>
Tab.vue
<template>
<div class="tab-pane" v-show="active">
<slot></slot>
</div>
</template>
<script>
import hub from '../eventhub';
export default {
props: {
'header': String
},
data() {
return {
active: false
}
},
mounted() {
this.$emit('tabcreated', this);
}
}
</script>
eventhub.js
import Vue from 'vue';
export default new Vue();
查看
<tabs>
<tab header="Test">
First Tab
</tab>
<tab header="Test2">
Second Tab
</tab>
<tab header="Test3">
Third Tab
</tab>
</tabs>
我尝试过以下事项:
$emit
的超时来测试它是否是计时问题(确实如此)
不)Tabs
组件的根元素中使用@tabcreated
模板如果...
this.$on
和
this.$emit
hub.$on
和hub.$emit
)Tabs
但这不适合我,因为我想在同一页面上多次使用this.$parent.$emit
组件,并使用&#34; eventhub&#34;功能不允许这样做。
$emit
但这只是感觉奇怪和错误。
文档说明可以在直接子组件上侦听由#banner {
background-image: url(http://lorempixel.com/400/200);
padding: 150px 0;
text-align: center;
background-size: cover;
color: white;
}
触发的事件
https://vuejs.org/v2/guide/migration.html#dispatch-and-broadcast-replaced
有没有人有想法?
答案 0 :(得分:0)
你是对的,在第二阶段,没有更多的$ dispatch。 $ emit可以用于单个组件,但它将作用于自己(this
)。建议的解决方案是使用全局事件管理器eventhub
。
eventhub可以存储在窗口对象中,无需导入即可在任何地方使用,我喜欢在我的main.js文件中声明如下:
window.bus = new Vue()
然后在任何组件中:
bus.$emit(...)
bus.$on(...)
它与this.$root.$emit
/ this.$root.$on
的作用相同。你说它在你调用this.$parent.$emit
时有效,但是这段代码在父组件中模拟了一个范围内的发射但是从孩子那里发射了,不好。
我在您的代码中理解的是,您希望拥有一组已创建的标签,但要对它们执行哪些操作?
您应该考虑更实用的方法,而不是将标签实例存储在父级中,然后从父级激活。
应在选项卡组件上声明activateTab
方法,并通过data
管理实例化,例如:
<template>
<div class="tabbed-pane">
<ul class="tab-list">
<tab v-for="tab in tabs" :header="tab.header"></tab>
</ul>
</div>
</template>
<script>
import hub from '../eventhub';
import Tab from 'path/to/Tab.vue';
export default {
components: [Tab],
props: [],
data() {
return {
tabs: ['First Tab', 'Second Tab', 'Third Tab']
}
}
}
</script>
<template>
<div class="tab tab-pane" @click:activeTab()>
<span v-show="active">Activated</span>
<span>{{ header }}</span>
</div>
</template>
<script>
import hub from '../eventhub';
export default {
props: {
'header': String
},
data() {
return {
active: false
}
},
methods: {
activeTab () {
this.active = true
}
}
}
</script>
这样,您的Tab
更加独立。对于父母/子女沟通,请牢记这一点:
如果您需要更复杂的状态管理,您一定要查看vuex。
<template>
<div class="tabbed-pane">
<ul class="tab-list">
<tab v-for="tabData in tabs" :custom="tabData"></tab>
</ul>
</div>
</template>
<script>
import Tab from 'path/to/Tab.vue';
export default {
components: [Tab],
props: [],
data() {
return {
tabs: [
{foo: "foo 1"},
{foo: "foo 2"}
{foo: "foo 3"}
]
}
}
}
</script>
<template>
<div class="tab tab-pane" @click:activeTab()>
<span v-show="active">Activated</span>
<span>{{ custom.foo }}</span>
</div>
</template>
<script>
export default {
props: ['custom'],
data() {
return {
active: false
}
},
methods: {
activeTab () {
this.active = true
}
}
}
</script>
答案 1 :(得分:0)
这就是我对VueJS(2)的看法,没有方便的方法来捕捉子组件发送到父组件的事件。
无论如何,如果您不想使用eventhub方法,那么另一种方法是,如果您只想在相关组件(子组件和父组件)之间进行事件通信而不是与非相关组件之间进行事件通信,那么您可以做这些步骤。
伪代码
// Parent vue component
Vue.component( 'parent_component' , {
// various codes here ...
data : {
parent_component_ref : this // reference to the parent component
},
methods : {
custom_event_cb : function() {
// custom method to execute when child component emits 'custom_event'
}
}
// various codes here ...
} );
// Parent component template
<div id="parent_component">
<child_component :parent_component_ref="parent_component_ref"></child_component>
</div>
// Child component
Vue.component( 'child_component' , {
// various codes here ...
props : [ 'parent_component_ref' ],
mounted : function() {
this.$on( 'custom_event' , this.parent_component_ref.custom_event_cb );
this.$emit( 'custom_event' );
},
// You can also, of course, emit the event on events inside the child component, ex. button click, etc..
} );
希望这有助于任何人。
答案 2 :(得分:0)
使用自{Vue v-on="$listeners"
以来可用的v2.4.0
。然后,您可以订阅父母所需的任何事件,请参阅fiddle。
来自Vue Support @ Discord的BogdanL
。