了解嵌套在VueJS中的组件

问题描述 投票:3回答:1

学习VueJS并在线阅读一些教程,包括关于vuejs.org的指南,我有一段时间了解组件如何嵌套并让它们通过道具进行通信。

简单的例子似乎没问题,但是下面的代码(略微调整但几乎超出了VueJS指南)给了我麻烦。

我似乎无法将'blog-item'嵌套在'blog-items中。

如果有人能够解释组件如何嵌套以及使用v-for指令,我将不胜感激。

我已经完成了很多教程,一切似乎都工作了一个组件嵌套在提供数据的顶层'app'组件中,​​但我似乎无法将其转换为下面的场景。

作为一个新手,我可能会错过一个关键概念或完全脱离了解Vue :)

希望你能帮忙。

谢谢

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Components Basics - from vuejs.org</title>
    <!-- development version, includes helpful console warnings -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>

  <body>
    <div id="app">

      <!-- This works. I get it. -->
      <div id="components-demo">
        <button-counter></button-counter>
        <button-counter></button-counter>
        <button-counter></button-counter>
      </div>

      <hr>

      <!-- This works too and I get it. -->
      <div id="blog-post-demo-simple">
        <blog-post-simple title="My journey with Vue"></blog-post-simple>
        <blog-post-simple title="Blogging with Vue"></blog-post-simple>
        <blog-post-simple title="Why Vue is so fun"></blog-post-simple>
      </div>

      <hr>

      <!-- This is where I'm totally confused -->
      <!-- How do I structure this to make sure blog-items is binding the 'post'  -->
      <!-- correctly? What is not clear to me is where the directives should be placed -->
      <!-- Vue keeps complainig with the following: -->
      <!-- Property or method "posts" is not defined on the instance but referenced during render -->
      <blog-items>
        <blog-item
          v-for="post in posts"
          v-bind:key="post.id"
          v-bind:post="post">
        </blog-item>
      </blog-items>

      <hr>

    </div>

    <script>

      // Define a new component called button-counter. Cool. No problem here.
      Vue.component('button-counter', {
        data: function () {
          return {
            count: 0
          }
        },
        template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
      })

      // This is also clear.
      Vue.component('blog-post-simple', {
        template:
        '<h3>{{title}}</h3>',
        props: {
          title: {
            type: String,
            required: true
          }
        }
      })

      Vue.component('blog-items', {
        data() { return {
            posts: [
              { id: 1, title: '1. My journey with Vue' },
              { id: 2, title: '2. Blogging with Vue' },
              { id: 3, title: '3. Why Vue is so fun' }
            ]
          }
        }
      })

      Vue.component('blog-item', {
        template:
        '<h2>{{post.title}}</h2>',
        props: ['post']
      })

      var app = new Vue({
        el: '#app'
      })

    </script>
  </body>
</html>
vue.js vue-component
1个回答
2
投票

请记住,当您访问模板中的属性时,您将从使用该模板的组件中获取该属性。在这种情况下,它是你的根#app组件。由于该组件没有名称为posts的属性或方法,因此Vue会抱怨。您需要做的是在blog-items组件的模板中移动该部分,因为该组件正在保留您的帖子。

所以你需要做的就是这个......

    <!-- This is where I'm totally confused -->
    <!-- How do I structure this to make sure blog-items is binding the 'post'  -->
    <!-- correctly? What is not clear to me is where the directives should be placed -->
    <!-- Vue keeps complainig with the following: -->
    <!-- Property or method "posts" is not defined on the instance but referenced during render -->
    <blog-items></blog-items>

Vue.component('blog-items', {
    template: `
    <div>
        <blog-item v-for="post in posts" v-bind:key="post.id" v-bind:post="post" />
    </div>
    `,
    data() {
        return {
            posts: [
            { id: 1, title: '1. My journey with Vue' },
            { id: 2, title: '2. Blogging with Vue' },
            { id: 3, title: '3. Why Vue is so fun' }
            ]
        }
    }
})

否则你将不得不求助于使用Scoped Slots,它允许你将属性/方法从子组件的范围暴露给父组件。

<blog-items>
    <template slot-scope="{ posts }">
        <blog-item v-for="post in posts" v-bind:key="post.id" v-bind:post="post">
        </blog-item>
    </template>
</blog-items>

Vue.component('blog-items', {
    template:`
    <div>
        <slot :posts="posts"></slot>
    </div>`,
    data() {
        return {
            posts: [
            { id: 1, title: '1. My journey with Vue' },
            { id: 2, title: '2. Blogging with Vue' },
            { id: 3, title: '3. Why Vue is so fun' }
            ]
        }
    }
})

我发现this特别有助于理解作用域如何工作。

© www.soinside.com 2019 - 2024. All rights reserved.