我尝试使用vue js 2创建一个包含可展开项目的列表。我的想法是,当我点击一个项目时,我希望它展开(显示它的内容),如果它是'尚未展开并关闭所有其他扩展元素。我创建了两个组件expandable-panel
和expandable-item
。我可以在里面有多种类型的内容,所以我想使用插槽。
我的代码:
ExpandablePanel
组件:
<template>
<div class="expandable-panel" @expanded="doStuff">
<slot></slot>
</div>
</template>
<script type="text/babel">
export default {
methods: {
doStuff: function() {
alert('expanded');
}
}
}
</script>
ExpandableItem
组件:
<template>
<div class="expandable-item" @click="toggleExpand">
<div class="expandable-item-header">
{{ title }}
</div>
<div class="expandable-item-body" v-if="expanded">
<slot></slot>
</div>
</div>
</template>
<script type="text/babel">
export default {
props: {
title: String
// expanded: {
// type: Boolean,
// default: true
// }
},
data: function() {
return {
expanded: true
}
},
methods: {
toggleExpand: function() {
this.expanded = !this.expanded;
this.$emit('expand');
}
}
}
</script>
我的HTML文件
<expandable-panel>
<expandable-item title='title 1'>Lorem ipsum...</expandable-item>
<expandable-item title='title 2'>Lorem ipsum...</expandable-item>
<expandable-item title='title 3'>Lorem ipsum...</expandable-item>
</expandable-panel>
我的应用和组件注册如下:
Vue.component('expandable-panel', require('./components/global/ExpandablePanel.vue'));
Vue.component('expandable-item', require('./components/global/ExpandableItem.vue'));
const app = new Vue({
el: '#app'
});
问题:
$emit
部分似乎无法到达父组件内的@expanded="doStuff"
。
即使它到达那里,我如何正确切换expanded
值?我可以为此使用道具吗?
现在,它会切换每个元素,但我无法更新其他元素。 谢谢
答案 0 :(得分:1)
你在这里有父和子之间的严格关系,所以你可以通过$ parent对象发出事件。
首先,在创建父对象时,使用this.$on
:
Vue.component('parent', {
template: `<div><slot></slot></div>`,
created: function() {
this.$on('event', function(message) {
alert(message);
})
}
});
然后在您的子组件内部使用$parent.$emit
Vue.component('child', {
template: `<button @click="$parent.$emit('event', 'From child')">I'm slot</button>`
});
答案 1 :(得分:0)
在ExpandablePanel
组件中:您应该只有@expand
,因为这是您从孩子那里发出的:
<template>
<div class="expandable-panel" @expand="doStuff">
<slot></slot>
</div>
</template>