vue 循环 递归组件_全局组件实现递归树,避免循环引用

概述

目录分类展示会通常要用到树形结构。本例结合vue的父子组件,采用递归渲染,实现一个基于树的curd小demo

知识点

父子组件递归渲染

class 样式对象写法,CSS伪元素 ::before 用法

vue 指令v-model,内联模板x-template

事件 dblclick blur, 防止事件传播修饰符 stop

引用父实例属性 $parent, 全局方法 Vue.set Vue.delete,子组件类型校验props

效果图

节点模型

树形结构,节点通常由数据域+子节点引用组成。缺少指向子节点引用的节点,称之为叶子节点。

同理,缺少父节点的节点谓之根节点。二者分别代表递归的出口和入口,在逻辑部分通过动态响应实现渲染效果。

下面这段代码描述了一个 data 基本treedata模型节点对象。 name 为 string 类型,children是数组类型。

var data = {

name: 'home',

children: [

{ name: 'hello.js' },

]

}

模板

以 x-template 形式描述当单个节点,然后递归复用该组件。

用文件与文件夹关系类比,文件则显示文件名,有文件夹则迭代。

所呈现的无非文件或文件夹,遇文件夹则递归使用组件本身。

用v-model实现双向绑定,双击文件名则达到文件变身文件夹,此外有相应的清除,删除,修改vue事件绑定

@click="toggle" @dblclick="changeType">

{{ name }}

@blur="doneEdit(name)"

@keyup.enter="doneEdit(name)"

@keyup.esc="cancelEdit()"

@click.stop @dblclick.stop >

[e]

[c]

[x]

[{{ open ? '-':'+'}}]

v-for="(treeData,index) in this.model.children" :

model="treeData" :key="index"/>

[append]

组件

注册全局组件 item

需要注意在直接在 DOM (即非字符串的模板如 x-template ) 中使用时只有 item 有效

约定校验数据类型是Object,属性名 model 视为组件接收父组件的模型数据接口

Vue.component('item', {

template: '#item-template',

// 类型校验,接收父组件传递过来的数据(只读)

props: {

model: Object,

},

computed: {

isFolder() {

return this.model.children && this.model.children.length

}

},

...

方法

动态增/删新节点

Vue.delete 清除文件夹下子节点

Vue.set 向响应式对象中添加一个新属性,需确保这个新属性同样是响应式的,以触发视图更新

methods: {

changeType() {

if (!this.isFolder) {

Vue.set(this.model, 'children', [])

this.addChild()

this.open = true

}

},

addChild() {

this.model.children.push({name: 'new file'})

},

delChild() {

if (this.isFolder) {

Vue.delete(this.model, 'children')

}

}

...

删除文件

通过 $prarent 引用父实例节点删除当前节点

用引用类型数组方法, indexOf 定位当前模型在父节点中的索引,splice 改变数据源

需要排除没有父节点(即当前节点是根节点情况),以及判断父节点是一个完整节点(是否存在有效子节点)

delFile() {

if (this.$parent.model === undefined) {

return

}

var parent = this.$parent.model.children

if (parent && Array.isArray(parent) && parent.length) {

parent.splice(parent.indexOf(this.model), 1)

}

},

源码

本作品采用《CC 协议》,转载必须注明作者和本文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值