vue父子组件参数传递
咱们个别应用prop给子组件传递参数,在子组件中应用$emit触发父组件中监听的事件,并且能够附带参数。
比方咱们封装了一个名为 NestedDir 的子组件(嵌套目录的意思),内容如下(用到了element ui组件):
<template>
<ul class="nest_wrapper">
<li v-for="(el, index) in nested" :key="index">
<div v-if="el.type ==='dir'" class="dir">
<p>{{el.name}}</p>
<div class="btn_group">
<el-button type="warning" size="mini" @click="add({id: el.id, type: 'dir'})">新增目录</el-button>
<el-button type="warning" size="mini" @click="add({id: el.id, type: 'file'})">新增文件</el-button>
</div>
</div>
<div v-if="el.type ==='file'" class="file">
<p>{{el.name}}</p>
</div>
<NestedDir v-if="el.children" :nested="el.children"/>
</li>
</ul>
</template>
<script>
export default {
name: "NestedDir",
props: {
nested: {
type: Array,
}
},
methods: {
add(el) {
this.$emit('change', el)
}
}
}
</script>
能够看出这个 NestedDir 接管父级传来的 nested 数组类型的数据,并且它的外部点击 新增目录、新增文件,能够触发 父级 监听的 change 事件。比拟非凡的是这个组件中调用了本人:
<NestedDir v-if="el.children" :nested="el.children"/>
因为咱们会传递给它的 nested 数据结构大略是上面的样子:
[{
"id": 1,
"name": "目录1",
"type": "dir",
"children": [{
"id": 2,
"name": "目录3",
"type": "dir",
"children": [],
"pid": 1
}, {
"id": 3,
"name": "文件2",
"type": "file",
"pid": 1
}]
}, {
"id": 4,
"name": "目录2",
"type": "dir",
"children": []
}, {
"id": 5,
"name": "文件1",
"type": "file",
"children": []
}]
父组件中调用:
<template>
<div style="width: 50%;box-shadow: 0 0 4px 2px rgba(0,0,0,.1);margin: 10px auto;padding-bottom: 10px;">
<!-- 顶部按钮组 -->
<div class="btn_group">
<el-button type="warning" size="mini" @click="showDialog({type: 'dir'})">新增目录</el-button>
<el-button type="warning" size="mini" @click="showDialog({type: 'file'})">新增文件</el-button>
</div>
<!-- 嵌套组件 -->
<NestedDir :nested="catalog" @change="handleChange"/>
<!-- 新增弹出框 -->
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="300px">
<el-form :model="form">
<el-form-item label="名称">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import NestedDir from "./NestedDir";
export default {
name: "directory",
components: {
NestedDir
},
created() {
this.catalog = this.getTree()
},
computed: {
maxId() {
return this.arr.lastIndex + 2
}
},
data() {
return {
arr: [
{id: 1, name: '目录1', type: 'dir', children: []},
{id: 2, name: '目录3', type: 'dir', children: [], pid: 1},
{id: 3, name: '文件2', type: 'file', pid: 1},
{id: 4, name: '目录2', type: 'dir', children: []},
{id: 5, name: '文件1', type: 'file'},
],
title: '',
dialogFormVisible: false,
form: {
id: '',
name: '',
type: '',
pid: ''
},
catalog: []
}
},
methods: {
handleChange(el) {
this.showDialog(el)
},
confirm() {
this.arr.push({...this.form})
this.dialogFormVisible = false
this.catalog = this.getTree()
this.form = {
id: '',
name: '',
type: '',
pid: ''
}
},
showDialog(el) {
if (el.type === 'dir') {
this.title = '新增目录'
this.form.children = []
this.form.type = 'dir'
} else {
this.title = '新增文件'
this.form.type = 'file'
}
if (el.id) {
this.form.pid = el.id
this.form.id = this.maxId
} else {
this.form.id = this.maxId
}
this.dialogFormVisible = true
},
getTree() {
let obj = {}
this.arr.forEach(item => {
if (item.pid) {
obj[item.pid].children.push(item)
} else {
item.children = []
obj[item.id] = item
}
})
return Object.values(obj)
}
}
}
</script>
<style scoped>
.btn_group {
padding: 20px 10px;
background-color: rgba(87, 129, 189, 0.13);
}
</style>
渲染出的页面是上面的样子:
深层递归组件事件失落
这样咱们结构出了一个实践上能够有限嵌套的目录构造,然而通过测试发现 在二级目录上的新增按钮点击是没有任何反馈的,起因是咱们在 NestedDir 中调用了它本人导致事件失落,因为它无奈触发父级的父级的监听事件。
todo 如何解决?
发表回复