我试图用vuejs创建手风琴。
我在网上找到了一些例子,但我想要的是不同的。对于SEO目的,我使用"是"和"内联模板",所以手风琴是在Vuejs中没有完全创建的静态。
我有2个问题/问题:
1)我需要添加一个类" is-active"在基于用户交互(点击)的组件上,因此我收到以下错误。
属性或方法" contentVisible"没有在实例上定义但是 在渲染期间引用。确保声明反应数据 数据选项中的属性。
这可能是因为我需要在实例级别设置它。但是" contentVisible"每个组件都有一个不同的值(真或假)。
所以我想在实例级别使用" contentVisible"和一个道具(通过实例传递)和子上的自定义事件来更新实例值。
2)可以工作,但它是一个静态数组。如何制作动态数组(不知道项目组件的数量)?
<div class="accordion">
<div>
<div class="accordion-item" is="item" inline-template :class="{ 'is-active': contentVisible}" >
<div>
<a @click="toggle" class="accordion-title"> Title A1</a>
<div v-show="contentVisible" class="accordion-content">albatros</div>
</div>
</div>
<div class="accordion-item" is="item" inline-template :class="{ 'is-active': contentVisible}" >
<div>
<a @click="toggle" class="accordion-title"> Title A2</a>
<div v-show="contentVisible" class="accordion-content">lorem ipsum</div>
</div>
</div>
</div>
var item = {
data: function() {
return {
contentVisible: true
}
},
methods: {
toggle: function(){
this.contentVisible = !this.contentVisible
}
}
}
new Vue({
el:'.accordion',
components: {
'item': item
}
})
更新 我创建了以下代码,但是将修改从组件发送到实例的自定义事件不起作用,tabactive未更改
var item = {
props: ['active'],
data: function() {
return {
contentVisible: false
}
},
methods: {
toggle: function(index){
this.contentVisible = !this.contentVisible;
this.active[index] = this.contentVisible;
**this.$emit('tabisactive', this.active);**
console.log(this.active);
}
}
}
new Vue({
el:'.accordion',
data: {
tabsactive: [false, false]
},
components: {
'item': item
}
})
<div class="accordion" **@tabisactive="tabsactive = $event"**>
<div class="accordion-item" is="item" inline-template :active="tabsactive" :class="{'is-active': tabsactive[0]}">
<div>
<a @click="toggle(0)" class="accordion-title"> Title A1</a>
<div v-show="contentVisible" class="accordion-content">albatros</div>
</div>
</div>
<div class="accordion-item" is="item" inline-template :active="tabsactive" :class="{'is-active': tabsactive[1]}">
<div>
<a @click="toggle(1)" class="accordion-title" > Title A2</a>
<div v-show="contentVisible" class="accordion-content">lorem ipsum</div>
</div>
</div>
</div>
答案 0 :(得分:1)
第1点:
您必须将contentVisible
定义为vue实例变量,因为您已使用vue指令v-show访问它,它会在vue data,watchers,{ {3}}等,如果找不到任何引用,则会抛出此错误。
由于您的accordion
元素与父组件相关联,您可能需要在其中添加contentVisible
数据,如下所示:
new Vue({
el:'.accordion',
data: {
contentVisible: true
}
components: {
'item': item
}
})
如果您有多个项目,您可以使用其他技术来展示其中一个项目,例如数据变量visibleItemIndex
可以从1更改为n-1,其中n是项目数。
在这种情况下,HTML中会有v-show="visibleItemIndex == currentIndex"
。
您也可以使用哈希来保存要显示的索引以及要折叠的索引。
第2点:
如果您有动态数组,则可以使用methods。你可以在这里看到文档。
答案 1 :(得分:0)
这对我有用:
<template>
<div>
<ul>
<li v-for="index in list" :key="index._id">
<button @click="contentVisible === index._id ? contentVisible = false : contentVisible = index._id">{{ index.title }}</button>
<p v-if='contentVisible === index._id'>{{ index.item }}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "sameName",
data() {
return {
contentVisible: false,
list: [
{
_id: id1,
title: title1,
item: item1
},
{
_id: id2,
title: title2,
item: item2
}
]
};
},
};
</script>
答案 2 :(得分:-1)
我真的很难理解你想要的是什么或为什么你想要它,但我认为这样做了吗?
Vue.component('accordion-item', {
template: '#accordion-item',
methods: {
toggle() {
if(this.contentVisible){
return
}
if(this.$parent.activeTab.length >= 2){
this.$parent.activeTab.shift()
}
this.$parent.activeTab.push(this)
}
},
computed: {
contentVisible() {
return this.$parent.activeTab.some(c => c === this)
}
}
})
const Accordion = Vue.extend({
data() {
return {
activeTab: []
}
},
methods: {
handleToggle($event) {
this.activeTab = []
}
}
})
document.querySelectorAll('.accordion').forEach(el => new Accordion().$mount(el))
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<template id="accordion-item">
<div class="accordion-item" :class="{ 'is-active': contentVisible}">
<a href="#" @click="toggle" class="accordion-title"><slot name="title"></slot></a>
<div v-show="contentVisible" class="accordion-content" @click="$emit('toggle', $event)">
<slot name="content"></slot>
</div>
</div>
</template>
<div class="accordion">
<accordion-item @toggle="handleToggle">
<p slot="title">a title</p>
<p slot="content">there are words here</p>
</accordion-item>
<accordion-item @toggle="handleToggle">
<p slot="title">titles are for clicking</p>
<p slot="content">you can also click on the words</p>
</accordion-item>
<accordion-item @toggle="handleToggle">
<p slot="title">and another</p>
<p slot="content">only two open at a time!</p>
</accordion-item>
<accordion-item @toggle="handleToggle">
<p slot="title">and #4</p>
<p slot="content">amazing</p>
</accordion-item>
</div>