在Vue.js中,递归组件调用自己,例如:
Vue.component('递归组件',{ template: `!-召唤我自己!-递归组件/递归组件});递归组件通常用于在博客上显示注释、嵌套菜单或基本相同类型的父子,尽管细节不同。例如:
现在我将向您展示如何有效地使用递归组件,我将通过构建一个可扩展/可收缩的树菜单来一步一步地完成。
数据结构
树用户界面的递归组件将是一些递归数据结构的可视化表示。在本教程中,我们将使用树结构,其中每个节点都是一个对象:
标签属性。
如果它有子节点和节点属性,则它是一个或多个节点的数组属性。
像所有的树结构一样,它必须有一个根节点,但它可以无限深。
let tree={ label: 'root ',node :[{ label : ' item 1 ',node :[{ label : ' item 1.1 ' },{ label: 'item1.2 ',node :[{ label : ' item 1 . 2 . 1 ' }]},{ label : ' item 2 ' } }递归组件
让我们制作一个递归组件来显示我们的数据结构,称为TreeMenu。它只显示当前节点的标签,并调用自身来显示任何子节点。文件名为TreeMenu.vue,内容如下:
Template div class=' tree-menu ' div { { label } }/div tree-menu v-for=' nodes in nodes ' : nodes=' node . nodes ' : label=' node . label '/tree-menu/div/Template script export default { props :[' label ',' nodes'],name :' tree-menu'}/script如果使用组件递归,必须首先给Vue.component一个全局定义,或者给它一个名称属性。否则,任何子组件都无法进一步调用它,您将得到一个不确定的“未定义组件错误”错误提示。
基本事件
像任何递归函数一样,你需要一个基本事件来结束递归,否则渲染会无限期地继续下去,最终会导致堆栈溢出。
在树菜单中,当我们到达一个没有子节点的节点时,我们希望停止递归。你可以通过v-if来实现这个函数,但是我们选择使用v-for来为我们隐式实现它;如果节点数组没有任何进一步的定义,将调用树菜单组件。Template.vue文件如下:
模板div class='树形菜单'.-如果“nodes”未定义,这将不会呈现-tree-menu v-for=“nodes”中的“node”/tree-menu/模板用法
我们现在如何使用这个组件?首先,我们声明一个Vue实例,其数据结构包括数据属性和已定义的treemenu组件。app.js文件如下:
从“”导入树菜单。/tree menu . vue ' let tree={ 0.} newvue ({el:' # app ',data: {tree},components: { treemenu } })请记住,我们的数据结构有一个根节点。我们递归调用主模板开头的TreeMenu组件,并使用根节点属性来支持:
div id=' app ' tree-menu : label=' tree。标签“:Nodes=”树。节点/树菜单/div如下所示:
正确体位
视觉识别子组件的“深度”就好,让用户从UI中获得数据结构的感觉。让我们缩进每一层的子节点来实现这个目标。
这是通过添加深度道具和树菜单的定义来实现的。我们将使用这个值来动态地将内联样式绑定到转换:我们将使用transform: translate的CSS规则来标记每个节点,从而创建缩进。Template.vue修改如下* *: * *
template div class=' tree-menu ' div : style=' indent ' { label } }/div tree-menu v-for=' nodes in nodes ' : nodes . nodes ' : label=' node . label ' : depth=' depth 1 '/tree-menu/div/template script export default { prosp :[' label ',' nodes ',' depth' ],name 3: ' tree-menu ',computed : { indent(){ return { transformdepth * 50 } px)` } } } }/script depth属性在主模板中从零开始。在上面的组件模板中,您可以看到该值在每次传递给任何子节点时都会递增。
div id=' app ' tree-menu : label=' tree。标签“:Nodes=”树。nodes ' : depth=' 0 '/tree-menu/div注意:记住v-bind深度的值,确保它是一个JavaScript数字类型,而不是字符串。
展开/折叠
由于递归数据结构可能非常大,因此显示它们的一个好的UI技术是隐藏除根节点之外的所有节点,以便用户可以根据需要展开或折叠节点。
因此,我们将添加一个本地属性showChildren。如果他的值为False,将不呈现子节点。应该通过单击节点来切换该值,因此我们需要使用一个名为toggleChildren的侦听器方法来管理它。Template.vue文件修改如下* *: * *
template div class=' tree-menu ' div : style=' indent ' @ click=' toggleChildren ' { label } }/div tree-menu v-if=' showChildren ' v-for=' nodes in nodes ' : nodes=' node . nodes ' : label=' node . label ' : depth=' depth 1 '/tree-menu/div/template script export default { prop :[' label ',' nodes ',' depth' ],data(){ return { showChildren 3333this.showChildren} } }/脚本摘要
这样,我们就有了一个工作树菜单。画龙点睛的一种方法是添加一个加号/减号图标,这样可以让UI显示的更加明显。我还在原来的showChildren的基础上增加了不错的字体和计算性能。