【问题标题】:How can I make a dynamic info page with both V-for and V-if?如何使用 V-for 和 V-if 制作动态信息页面?
【发布时间】:2020-10-13 19:49:31
【问题描述】:

大家好,我只是尝试在这里实现这个布局:

所以基本上这家公司有不同类别的服务,然后有不同的子选项,然后他们有具体的详细信息。

我的 JSON 如下所示:

    {
        "services": [{
                "name": "COVID-19",
                "options": [
                    "COVID-19 Temperature Screening System"
                ],
                "information": {
                    "images": [
                        "http://placekitten.com/300/300"
                    ],
                    "description": "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, in."
                }
            },
            {
                "name": "Home",
                "options": [
                    "Camera",
                    "Fire Alarm",
                    "Motion Sensor"
                ],
                "information": {
                    "images": [
                        "http://placekitten.com/300/300"
                    ],
                    "description": "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, in."
                }
            },
....

到目前为止,我在这里遇到的问题是我想一起使用 v-if 和 v-for 来根据用户点击的内容来更改显示的产品。它抛出这个错误:

26:11 错误“v-for”指令中的“this.JSON”表达式 应替换为返回过滤的计算属性 代替数组。您不应该将 'v-for' 与 'v-if' 混用

任何人都可以帮助我使用计算属性来执行此操作,因为我对这意味着什么感到困惑,这里是服务页面:

<template>
  <div class="services">
    <div class="header services__header">
      <h1 :class="$mq">Services</h1>
    </div>
    <div class="services__services-container">
      <div class="services__services-container__category-selection">
        <!-- GENERATE CATEGORIES -->
        <div
          class="services__services-container__category-selection__category"
          v-for="(item, index) in this.JSON"
          :key="`category-${index}`"
          :class="$mq"
        >
          <input type="radio" :name="item.name" :value="item.name" v-model="currentCategory" />
          <label :for="item.name">{{item.name}}</label>
        </div>
      </div>
      <!-- GENERATE SERVICES -->
      <div class="services__services-container__service-selection">
        <div
          class="services__services-container__service-selection__service"
          v-for="(item, index) in this.JSON"
          :key="`service-${index}`"
          :class="$mq"
          v-if="currentCategory === item.name"
        >
        <!-- ^^^ THIS V-IF IS NOT ALLOWED -->
          <div
            class="services__services-container__service-selection__service__wrapper"
            v-for="(option, index) in item.options"
            :key="`option-${index}`"
            :class="$mq"
          >
            <input type="radio" :name="option" :value="option" v-model="currentService" />
            <label :for="option">{{option.optionName}}</label>
          </div>
        </div>
      </div>
      <!-- GENERATE DESCRIPTIONS -->
      <div class="services__services-container__product-description">
        <div
          class="services__services-container__product-description__description"
          v-for="(item, index) in this.JSON"
          :key="`service-${index}`"
          :class="$mq"
        >
          <div v-for="(option, index) in item.options" :key="`option-${index}`" :class="$mq">
            <img :src="option.images" alt />
            <p>{{option.description}}</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import services from "@/JSON/services.json";
export default {
  name: "Services",
  data: function() {
    return {
      JSON: [],
      currentCategory: "",
      currentService: ""
    };
  },
  created: function() {
    //TO TEST
    this.JSON = services.services;
    this.JSON.forEach(element => {
      console.log(element);
    });
  }
};
</script>

<style lang="scss">
@import "@/scss/variables.scss";
@import "@/scss/button.scss";
@import "@/scss/header.scss";
@import "@/scss/input.scss";
.services {
  width: 100%;
  height: auto;
  display: grid;
  grid-template-rows: 15vh auto auto auto;

  &__services-container {
    padding: 2rem;
    & input {
      margin-right: 0.5rem;
    }

    &__category-selection {
      background-color: $colour-green;
      padding: 1rem;
      margin-bottom: 1rem;
    }

    &__service-selection {
      padding: 1rem;
      margin-bottom: 1rem;
      &__service {
        background-color: $colour-blue;
        margin-bottom: 1rem;
      }
    }

    &__product-description {
      background-color: $new-service;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      &__description {
        & img {
          margin-bottom: 1rem;
        }
        background-color: pink;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        text-align: center;
      }
    }
  }
}
</style>

我的脚本部分:

<script>
import services from "@/JSON/services.json";
export default {
  name: "Services",
  data: function() {
    return {
      JSON: [],
      currentCategory: "Home",
      currentService: ""
    };
  },
  created: function() {
    //TO TEST
    this.JSON = services.services;
    this.JSON.forEach(element => {
      console.log(element);
    });
  }
};
</script>

【问题讨论】:

    标签: javascript arrays json vue.js for-loop


    【解决方案1】:

    26:11 错误“v-for”指令中的“this.JSON”表达式应该 替换为返回过滤数组的计算属性 反而。你不应该把 'v-for' 和 'v-if' 混用

    该错误消息的意思是,您应该在计算属性中应用您的 v-if 语句(充当服务的过滤器),而不是在模板中。

    所以不要这样:

    <template>
      <div
              class="services__services-container__service-selection__service"
              v-for="(item, index) in this.JSON"
              :key="`service-${index}`"
              :class="$mq"
              v-if="currentCategory === item.name"
            >
    </template>
    

    试试这个:

    <template>
      <div
              class="services__services-container__service-selection__service"
              v-for="(item, index) in filteredJson"
              :key="`service-${index}`"
              :class="$mq"
            >
    </template>
    

    所以您的脚本需要计算属性“filteredJson”:

    <script>
    import services from "@/JSON/services.json";
    export default {
      name: "Services",
      data: function() {
        return {
          JSON: [],
          currentCategory: "",
          currentService: ""
        };
      },
      created: function() {
        //TO TEST
        this.JSON = services.services;
        this.JSON.forEach(element => {
          console.log(element);
        });
      },
      computed: {
        filteredJson() {
          return this.JSON.filter(item=> currentCategory === item.name);
        }
      }
    };
    </script>
    
    

    【讨论】:

      【解决方案2】:

      我会那样做,选择的收音机就是这样的项目本身:

        <div class="services">
          <div class="header services__header">
            {{currentCategory}}
            <h1 :class="$mq">Services</h1>
          </div>
          <div class="services__services-container">
            <div class="services__services-container__category-selection">
              <!-- GENERATE CATEGORIES -->
              <div class="services__services-container__category-selection__category" v-for="(item, index) in services" :key="`category-${index}`" :class="$mq">
                <input type="radio" :name="item.name" :value="item" v-model="currentCategory" />
                <label :for="item.name">{{item.name}}</label>
              </div>
            </div>
            <!-- GENERATE SERVICES -->
            <div class="services__services-container__service-selection" v-if="currentCategory!=null">
              <div class="services__services-container__service-selection__service" :class="$mq">
                <!-- ^^^ THIS V-IF IS NOT ALLOWED -->
                <div class="services__services-container__service-selection__service__wrapper" v-for="(option, index) in currentCategory.options" :key="`option-${index}`" :class="$mq">
                  {{option}}
                  <input type="radio" :name="option" :value="option" v-model="currentService" />
                  <label :for="option">{{option.optionName}}</label>
                </div>
              </div>
            </div>
            <!-- GENERATE DESCRIPTIONS -->
            {{currentService}}
            <div class="services__services-container__product-description" v-if="currentService!=null">
              <div class="services__services-container__product-description__description" :class="$mq">
                <div :class="$mq">
                  <img :src="currentCategory.information.images" alt />
                  <p>{{currentCategory.information.description}}</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      

      【讨论】:

      • 感谢您的帮助!我检查了你的代码,它给了我一个错误:TypeError:“_vm.currentCategory.information is undefined”。如何在数据方法中将收音机建模为项目本身?
      • 没关系,我将最后部分 img 和 p 中的 currentCategory 更改为 currentService 并且它可以工作。非常感谢!天才
      猜你喜欢
      • 2020-06-28
      • 1970-01-01
      • 2019-12-20
      • 2023-02-22
      • 2021-02-28
      • 2018-12-14
      • 1970-01-01
      • 2021-02-21
      • 2018-08-02
      相关资源
      最近更新 更多