Vue.js 元件 – 元件間的迴圈引用示例

17biu發表於2017-12-26

寫了大大小小不少基於vue的專案,但是基本沒用到過元件迴圈引用的知識。
為了查缺補漏,照著官方文件擼一個DEMO:元件之間的迴圈引用

本人的執行版本為 vue-cli@2.8.1,啟用專案後,將以下 js 檔案和 vue 檔案放置在相應的目錄中執行。

main.js

import Vue from `vue`
import App from `./App`
new Vue({
  el: `#app`,
  template: `<App/>`,
  components: { App }
})

main.js 匯入 App 元件,並在 components 中註冊 App 元件。

App.vue

<template>
  <div id="app">
    <li v-for="folder in folders">
      <tree-folder v-bind:folder="folder"></tree-folder>
    </li>
  </div>
</template>
<script>
  import TreeFolder from `./components/tree-folder`
  export default {
    data: function () {
      return {
        folders: [
          {
            name: `folder1`,
            children: [{
              name: `folder1 - folder1`,
              children: [{
                name: `folder1 - folder1 - folder1`
              }]
            }, {
              name: `folder1 - folder2`,
              children: [{
                name: `folder1 - folder2 - folder1`
              }, {
                name: `folder1 - folder2 - folder2`
              }]
            }]
          },
          {
            name: `folder 2`,
            children: [{
              name: `folder2 - folder1`,
              children: [{
                name: `folder2 - folder1 - folder1`
              }]
            }, {
              name: `folder2 - folder2`,
              children: [{
                name: `folder2-content1`
              }]
            }]
          },
          {
            name: `folder 3`,
            children: [{
              name: `folder3 - folder1`,
              children: [{
                name: `folder3 - folder1 - folder1`
              }]
            }, {
              name: `folder3 - folder2`,
              children: [{
                name: `folder3-content1`
              }]
            }]
          }
        ]
      }
    },
    components: {
      TreeFolder
    }
  }
</script>

App 元件匯入 TreeFolder 元件,並在 components 中註冊 TreeFolder 元件。

components/tree-folder.vue

<template>
  <p>
    <span>{{ folder.name }}</span>
    <tree-folder-contents :children="folder.children"></tree-folder-contents>
  </p>
</template>
<script>
  // 官方文件:「在我們的例子中,將 tree-folder 元件做為切入起點。我們知道製造矛盾的是 tree-folder-contents 子元件,所以我們在 tree-folder 元件的生命週期鉤子函式 beforeCreate 中去註冊 tree-folder-contents 元件」
  export default {
    props: [`folder`],
    data: function () {
      return {}
    },
    beforeCreate: function () {
    // 官方文件給出的是require
    // this.$options.components.TreeFolderContents = require(`./tree-folder-contents.vue`)
    // 在基於vue-cli@2.8.1按照上面的寫法還是會報錯
    // Failed to mount component: template or render function not defined.
    // 所以我們應該改為基於es6的寫法非同步載入一個元件如下
      this.$options.components.TreeFolderContents = () => import(`./tree-folder-contents.vue`)
    }
  }
</script>

TreeFolder 元件匯入 TreeFolderContents 元件,並在 components 中註冊 TreeFolderContents 元件。

components/tree-folder-contents.vue

<template>
  <ul>
    <li v-for="child in children">
      <tree-folder v-if="child.children" :folder="child"></tree-folder>
      <span v-else>{{ child.name }}</span>
    </li>
  </ul>
</template>
<script>
  import TreeFolder from `./tree-folder`
  export default {
    props: [`children`],
    components: {
      TreeFolder
    }
  }
</script>

TreeFolderContents 元件又匯入 TreeFolder 元件,並在 components 中註冊 TreeFolder 元件,產生了迴圈引用。

參考資料:
1、http://lizhihua.me/2016/12/24…
2、https://cn.vuejs.org/v2/guide…
3、https://cn.vuejs.org/v2/guide…

歡迎關注我的部落格 [http://www.17biu.cn]

相關文章