首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定制手风琴手风琴,一次一件,在Vue

定制手风琴手风琴,一次一件,在Vue
EN

Stack Overflow用户
提问于 2022-04-28 11:19:53
回答 1查看 532关注 0票数 1

我使用Vue与Nuxt 2,并在我的自定义手风琴组件有问题。

我想一次拉一架手风琴。但实际上发生的是,如果我点击第一个手风琴链接,第一个链接(手风琴)的主体正在打开。而没有关闭第一个,如果我打开第二个环节(手风琴),第二个手风琴身体也打开。我想避免这样做。如果我想打开其他手风琴,打开的手风琴应该先关闭。那么,我如何在不使用任何库的情况下,以vue方式实现这一点。

手风琴切换过程:,我使用ACTIVE值来切换手风琴,方法是在锚标记上添加aria-expended = "true"。同时,我正在显示或隐藏基于accordion-item-bodyACTIVE值。

我的组件手风琴:

代码语言:javascript
复制
<template>
  <div id="accordion" ref="accordion" class="accordion">
    <slot />
  </div>
</template>

<script lang="ts">
import Vue from "vue"
import { props } from "./props"

export default Vue.extend({
  name: "Accordion",
  props,
  created() {
    this.$nuxt.$off("eventName")
    this.$nuxt.$on("eventName", ($event: any) => this.toggleActive($event))
  },
  methods: {
    toggleActive(e: any) {
      console.log(e)
    },
  },
})
</script>

我的AccordionItem组件:

代码语言:javascript
复制
<template>
  <div class="accordion-item" role="tab">
    <div class="accordion-item-header">
      <a
        :aria-expanded="active"
        @click.prevent=";(active = !active), $nuxt.$emit('eventName', active)"
      >
        {{ title }}

        <span
          class="material-icons"
        >
          expand_more
        </span>
      </a>
    </div>
    <transition name="accordion">
      <div v-show="active" class="accordion-item-body" role="tabpanel">
        <slot />
      </div>
    </transition>
  </div>
</template>

<script lang="ts">
import Vue from "vue"
export default Vue.extend({
  name: "AccordionItem",
  props: {
    title: {
      type: String,
      required: true,
    },
    id: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      active: false,
    }
  },
})
</script>

手风琴和在父母中的AccordionItem用法:

代码语言:javascript
复制
<Accordion :items="items">
  <AccordionItem
    v-for="item in items"
    :id="item.id"
    :key="item.id"
    :title="item.title"
  >
    <div v-html="item.description"></div>
  </AccordionItem>
</Accordion>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-28 13:31:24

这里有一个简单而有效的解决方案(当然,我没有实现样式设计,但功能运行得很好)。

包装器

代码语言:javascript
复制
<template>
  <div>
    <accordion
      v-for="(item, index) in list"
      :key="item.id"
      :item="item"
      :active-index="currentlyActiveIndex"
      :item-index="index"
      @update:itemIndex="currentlyActiveIndex = $event"
    ></accordion>
  </div>
</template>

<script>
export default {
  name: 'AccordionList',
  data() {
    return {
      list: [
        { id: 1, name: 'hello' },
        { id: 2, name: 'world' },
        { id: 3, name: 'swag' },
      ],
      currentlyActiveIndex: null,
    }
  },
}
</script>

Accordion.vue

代码语言:javascript
复制
<template>
  <div>
    <button @click="updateIndex">get this index: {{ itemIndex }}</button>
    <span v-show="activeIndex === itemIndex">{{ item.name }}</span>
  </div>
</template>

<script>
export default {
  name: 'Accordion',
  props: {
    item: {
      type: Object,
      default: () => {},
    },
    activeIndex: {
      type: Number,
      default: null,
    },
    itemIndex: {
      type: Number,
      default: null,
    },
  },
  methods: {
    updateIndex() {
      console.log('index updated:', this.itemIndex)
      this.$emit('update:itemIndex', this.itemIndex)
    },
  },
}
</script>

这也可以通过类似{ id: 1, name: 'hello', isActive: false }这样的方法来实现,但这两种方法在这里都是有效的。

PS:我也不知道如何使用TS,但我相信你自己也能理解这个部分(我猜这里不是阻断剂)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72042753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档