【问题标题】:vue.js Property or method is not defined - nested componentsvue.js 属性或方法未定义 - 嵌套组件
【发布时间】:2021-10-18 21:45:12
【问题描述】:

我正在创建一个静态网站,其中有选项卡(反应属性),并且每个选项卡都应该有许多带有图像和文本的卡片(反应属性)。 我收到此警告:

[Vue 警告]:属性或方法“recipes”未在实例上定义,但在渲染期间被引用。通过初始化该属性,确保该属性在数据选项或基于类的组件中是反应性的。

我做错了什么?

我的 HTML

 <main id="app">
  <header>
    <nav>
      <ul>
        <li v-for="(tab, tabName) in tabs" :key="tabName">
          <button class="tab" @click="setTabActive(tabName)" :class="{'active': tabName === activeTab}">
            <span class="tab-copy">{{ tabName }}</span>
            <span class="tab-background">
            </span>
          </button>
        </li>
      </ul>
    </nav>
  </header>
  <article>
    <div class="container">
      <transition name="fade" mode="out-in" appear :duration="500">
        <tab-content v-for="(tabContent, t) in tabs" :data="tabContent" :key="'content'+t" v-if="t === activeTab" inline-template>
          <div class="content-wrapper">
            <div class="recipes" v-for="recipe in recipes">

              <a href="#" class="recipe-card__card-link"></a>
              <img :src="recipe.image" alt="" class="recipe-card__image">
              <div class="recipe-card__text-wrapper">
                <h2 class="recipe-card__title">{{recipe.name}}</h2>
                <div class="recipe-card__details-wrapper">
                  <p class="recipe-card__excerpt">{{recipe.body}}</p>
                  <a href="#" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
                </div>
              </div>
            </div>
          </div>
        </tab-content>
      </transition>
    </div>
  </article>
</main>

我的 Vue.js

new Vue({
  el: "#app",
  data: {
   tabs: {
  "Breakfast": {
    recipes : [
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
    ],
  },
  "Soup": {
    recipes : [
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Great Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Great Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
    ],
       },
  "Salad": {
    recipes : [
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Amazing Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Amazing Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
    ],
  },
  "Main": {
    recipes : [
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
    ],
  },
  "Dessert": {
    recipes : [
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
    ],
   },
  "Drink": {
    recipes : [
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
      {
        image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
        name: "Awesome Title",
        body:
          "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
      },
    ],
  }
},
activeTab: "Breakfast"
},
computed: {
  tabContent() {
    return this.tabs[this.activeTab];
 }
},
methods: {
  setTabActive(tab) {
    this.activeTab = tab;
 }
},
components:{
  'TabContent': {
    props: {
      data: Object,
  },
},
'recipes': {
  props: ['image', 'name', 'body'],
 },
},
})

【问题讨论】:

    标签: javascript html vue.js


    【解决方案1】:

    你可以试试&lt;div class="recipes" v-for="(recipe, i) in data.recipes" :key="i"&gt;

    new Vue({
      el: "#app",
      data() {
      return {
       tabs: {
      "Breakfast": {
        recipes : [
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
        ],
      },
      "Soup": {
        recipes : [
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Great Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Great Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
        ],
           },
      "Salad": {
        recipes : [
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Amazing Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Amazing Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
        ],
      },
      "Main": {
        recipes : [
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
        ],
      },
      "Dessert": {
        recipes : [
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
        ],
       },
      "Drink": {
        recipes : [
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
          {
            image: "https://images.pexels.com/photos/127513/pexels-photo-127513.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260",
            name: "Awesome Title",
            body:
              "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ab nam alias architecto officia, dolores animi qui debitis incidunt eius temporibus nostrum nihil soluta commodi molestiae necessitatibus ducimus amet. Suscipit, saepe!",
          },
        ],
      }
     
    },
    activeTab: "Breakfast"
    }
    },
    computed: {
      tabContent() {
        return this.tabs[this.activeTab];
     }
    },
    methods: {
      setTabActive(tab) {
        this.activeTab = tab;
     }
    },
    components:{
      'TabContent': {
        props: {
          data: Object,
      },
    },
    'recipes': {
      props: ['image', 'name', 'body'],
     },
    },
    })
    
    Vue.config.productionTip = false
    Vue.config.devtools = false
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <main id="app">
      <header>
        <nav>
          <ul>
            <li v-for="(tab, tabName) in tabs" :key="tabName">
              <button class="tab" @click="setTabActive(tabName)" :class="{'active': tabName === activeTab}">
                <span class="tab-copy">{{ tabName }}</span>
                <span class="tab-background">
                </span>
              </button>
            </li>
          </ul>
        </nav>
      </header>
      <article>
        <div class="container">
          <transition name="fade" mode="out-in" appear :duration="500">
            <tab-content v-for="(tabContent, t) in tabs" :data="tabContent" :key="'content'+t" v-if="t === activeTab" inline-template>
              <div class="content-wrapper">
                <div class="recipes" v-for="(recipe, i) in data.recipes" :key="i">
    
                  <a href="#" class="recipe-card__card-link"></a>
                  <img :src="recipe.image" alt="" class="recipe-card__image">
                  <div class="recipe-card__text-wrapper">
                    <h2 class="recipe-card__title">{{recipe.name}}</h2>
                    <div class="recipe-card__details-wrapper">
                      <p class="recipe-card__excerpt">{{recipe.body}}</p>
                      <a href="#" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
                    </div>
                  </div>
                </div>
              </div>
            </tab-content>
          </transition>
        </div>
      </article>
    </main>

    【讨论】:

      【解决方案2】:

      您在“数据”属性之外声明了“食谱”。这样的自定义属性不会出现在您的模板部分。

      在你的食谱循环中:

      <div class="recipes" v-for="recipe in recipes">
      

      试试:

      <div class="recipes" v-for="recipe in tabContent.recipes">
      

      【讨论】:

        【解决方案3】:

        您当前所获得的内容试图读取不存在的this.recipes。由于食谱数组的范围为给定选项卡,因此您只需替换

        v-for="recipe in recipes"
        

        v-for="recipe in tabContent.recipes"
        

        【讨论】:

          猜你喜欢
          • 2021-03-05
          • 2019-12-25
          • 2017-08-28
          • 1970-01-01
          • 1970-01-01
          • 2020-03-24
          • 2018-12-06
          • 2019-11-24
          • 2015-08-10
          相关资源
          最近更新 更多