8

写了大大小小不少基于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]

17biu
132 声望1 粉丝

css is beautiful,