vue.js - 了解 VueJS 中的组件嵌套

标签 vue.js vue-component

学习 VueJS 并学习了一些在线教程,包括 vuejs.org 上的指南,我花了很长时间了解如何嵌套组件并让它们通过 props 进行通信。

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

我似乎无法将“博客项目”嵌套在“博客项目”中。

如果有人能解释如何嵌套组件以及使用 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>

最佳答案

请记住,当您访问模板中的属性时,您是从使用该模板的组件中获取该属性。在本例中,它是您的根 #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特别有助于理解作用域插槽的工作原理。

关于vue.js - 了解 VueJS 中的组件嵌套,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52730411/

相关文章:

Vue.js 从子组件关闭模态

javascript - Vue 中传递事件方法

javascript - 如何使用 Vue.js 下载图像而不显示它们?

javascript - 使用 Masonry.JS 和 Vue.JS

vue.js - yarn 在后台服务

javascript - Vue.js-Vuex 更新数组内部状态中的对象未反射(reflect)在组件 DOM 中

javascript - 使用子组件的 $emit 将数据发送到父组件不适用于 Vue

javascript - 如何从模板 vue.js 2 调用 javascript?

vue.js - 无法在 VueJs 中使用 V-for 渲染列表

javascript - 如何获取事件元素/当前查看的部分的标题并显示它(Bootstrap Vue ScrollSpy)?