我目前正在做一个小项目,它需要我创建用本地.json文件中的数据动态填充的选项卡.我已经让选项卡标题正常工作了,但是每次单击选项卡时,它只显示第一个数据索引中的内容.我已经try 了遍历数据和其他一些我在这一点上已经忘记的事情,但没有运气,所以如果有任何帮助,我将不胜感激.

需要注意的一点是,这是我第一次使用Vue.我知道用Vue本身做这件事可能有一种更简单的方法,但在这个阶段我更愿意使用香草JS,因为我更熟悉它.我也没有使用标签ID,因为它是动态的.

这是我目前拥有的代码,如果有什么需要我补充的,请告诉我.

Html:

<template>
<section class="tab__container">
    <div class="tab__sidebar">
        <button class="tab__button" v-for="data in data" :key="data.title">{{ data.title }}</button>
    </div>
    <div class="tab__content" v-for="data in data" :key="data.content">
        <p v-html="data.content"></p>
    </div>
</section>

Css:以下内容:

<script>
import data from '../assets/data.json'

export default {
  props: ['title', 'content'],
  data() {
    return {
      data: data
    }
  }
}
</script>

<style>

.tab__container {
    display: none;
}

@media (min-width: 769px) {
    .tab__container {
        display: flex;
        border: 1px solid #d2d2d2;
    }

    .tab__sidebar {
        flex-direction: row;
        width: 125px;
        flex-shrink: 0;
        background: #cccccc;
    }

    .tab__button {
        display: block;
        padding: 10px;
        background: #eeeeee;
        border: none;
        width: 100%;
        outline: none;
        cursor: pointer;
    }

    .tab__button:active {
        background: #dddddd;
    }

    .tab__button:not(:last-of-type) {
        border-bottom: 1px solid #cccccc;
    }

    .tab__button.is__active {
        font-weight: bold;
        border-right: 2px solid #009879;
        background: #dddddd;
    }

    .tab__content {
        padding: 20px;
        font-size: 18px;
        display: none;
    }

    .tab__content.is__active {
        display: block;
    }
}
</style>

JavaScript:如下所示:

document.querySelectorAll(".tab__button").forEach(button => {
    button.addEventListener("click", () => {
        var sidebar = button.parentElement;
        var tabContainer = sidebar.parentElement;
        var tabToActivate = tabContainer.querySelector(".tab__content");
      
        sidebar.querySelectorAll(".tab__button").forEach(button => {
            button.classList.remove("is__active");
        });

        tabContainer.querySelectorAll(".tab__content").forEach(tab => {
            tab.classList.remove("is__active");
        });

        button.classList.add("is__active");
        tabToActivate.classList.add("is__active");
    });
});

.json数据:

[
    {
      "title": "Section 1",
      "content": "<p>Maecenas nec semper ante, pellentesque posuere lorem. Nullam ipsum massa, consequat eget urna ut, pulvinar dignissim lorem. Nulla facilisi. Nam mattis eleifend metus. Fusce at commodo lorem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus pellentesque elit sem, vel blandit posuere.</p>"
    },
    {
      "title": "Section 2",
      "content": "<p>Mauris a orci sodales, scelerisque velit vitae, gravida nisl. Ut non laoreet eros, vel laoreet nisi. Praesent sed dolor dui. Proin non fringilla quam. Aliquam erat volutpat. Vestibulum vel arcu semper, lobortis turpis ac, ultricies nisi. Praesent id.</p>"
    },
    {
      "title": "Section 3",
      "content": "<p>Sed elementum sapien ut sapien imperdiet, eu venenatis enim rhoncus. Praesent euismod tincidunt rhoncus. Duis cras amet:</p><ul><li>List item one</li><li>List item two</li><li>List item three</li></ul>"
    },
    {
      "title": "Section 4",
      "content": "<p>Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.</p><p>Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>"
    }
  ]

推荐答案

    const data = [
        {
          "title": "Section 1",
          "content": "<p>Maecenas nec semper ante, pellentesque posuere lorem. Nullam ipsum massa, consequat eget urna ut, pulvinar dignissim lorem. Nulla facilisi. Nam mattis eleifend metus. Fusce at commodo lorem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus pellentesque elit sem, vel blandit posuere.</p>"
        },
        {
          "title": "Section 2",
          "content": "<p>Mauris a orci sodales, scelerisque velit vitae, gravida nisl. Ut non laoreet eros, vel laoreet nisi. Praesent sed dolor dui. Proin non fringilla quam. Aliquam erat volutpat. Vestibulum vel arcu semper, lobortis turpis ac, ultricies nisi. Praesent id.</p>"
        },
        {
          "title": "Section 3",
          "content": "<p>Sed elementum sapien ut sapien imperdiet, eu venenatis enim rhoncus. Praesent euismod tincidunt rhoncus. Duis cras amet:</p><ul><li>List item one</li><li>List item two</li><li>List item three</li></ul>"
        },
        {
          "title": "Section 4",
          "content": "<p>Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.</p><p>Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>"
        }
     ];
  
 new Vue({
  el: '#app',
  data() {
    return {
      data,
      activeTabIndex: 0,
    }
  },
  computed: {
    activeContent() {
      return this.data[this.activeTabIndex]?.content;
    }
  
  }
 })
        .tab__container {
    display: none;
}

@media (min-width: 769px) {
    .tab__container {
        display: flex;
        border: 1px solid #d2d2d2;
    }

    .tab__sidebar {
        flex-direction: row;
        width: 125px;
        flex-shrink: 0;
        background: #cccccc;
    }

    .tab__button {
        display: block;
        padding: 10px;
        background: #eeeeee;
        border: none;
        width: 100%;
        outline: none;
        cursor: pointer;
    }

    .tab__button:active {
        background: #dddddd;
    }

    .tab__button:not(:last-of-type) {
        border-bottom: 1px solid #cccccc;
    }

    .tab__button.is__active {
        font-weight: bold;
        border-right: 2px solid #009879;
        background: #dddddd;
    }

    .tab__content {
        padding: 20px;
        font-size: 18px;
        display: block;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

    <main id="app">
      <section class="tab__container">
        <div class="tab__sidebar">
            <button class="tab__button"
                v-for="(data, index) in data"
                :key="data.title"
                @click="activeTabIndex = index">{{ data.title }}</button>
        </div>
        <div class="tab__content">
            <p v-html="activeContent"></p>
        </div>
      </section>
    </main>

Javascript相关问答推荐

html + java script!需要帮助来了解为什么我得到(无效的用户名或密码)

你怎么看啦啦队的回应?

如何使onPaste事件与可拖动的HTML元素一起工作?

如何强制Sphinx中的自定义js/css文件始终加载更改而不缓存?

检索相加到点的子项

DOM不自动更新,尽管运行倒计时TS,JS

为什么这个.add.group({})在教程中运行得很好,但在我的游戏中就不行了?

FireBase FiRestore安全规则-嵌套对象的MapDiff

与在编剧中具有动态价值的定位器交互

ReferenceError:无法在初始化之前访问setData

连续添加promise 时,如何在所有promise 都已结算时解除加载覆盖

在传单的图像覆盖中重新着色特定 colored颜色 的所有像素

更改管线时不渲染组件的react

如何为Reaction应用程序创建仅登录的路由?

V-如果使用数组[vue3]中的布尔结果

面临错误:未捕获RangeError-超出最大调用堆栈大小

Chart.js折线图动态更改其y轴

JavaScriptpromise 和同步行为

我不能把数字加在一起,尽管我使用了parseFloat,但我仍然得到了NaN

我的本地计算机上的时区偏移量加倍,但在UTC服务器上工作正常.为什么?