Vue组件传参,vue父组件给子组件传参
这篇文章主要介绍了某视频剪辑软件嵌套组件传参实例分享,本文以一个某视频剪辑软件递归组件为例,探究多层嵌套后事件无法触发的问题,我们可以通过查看一演示,便于快速了解,下文列举例子需要的小伙伴可以参考一下
目录
递归嵌套组件参数传递深层递归组件事件丢失事件总线什么事EventBus?前言:
假设我们已经了解某视频剪辑软件组件常见的有父子组件通信,兄弟组件通信。而父子组件通信很简单,父组件会通过小道具向下传数据给子组件,当子组件有事情要告诉父组件时会通过$emit事件告诉父组件。那么当两个组件之间不是父子关系,怎样传递数据呢?
先来看一下这个例子:
递归嵌套组件参数传递
我们封装了一个名为内斯特迪尔的子组件(嵌套目录的意思),内容如下(用到了元素用户界面组件):
!-内斯特迪尔
模板
ul class=嵌套包装
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,类型: 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
嵌套目录v-if= El。 children :nested= El。儿童/
/李
/ul
/模板
脚本
导出默认值{
姓名:"内斯特迪尔",
道具:{
嵌套:{
类型:数组,
}
},
方法:{
添加(el) {
这个emit(change ,el)
}
}
}
/脚本
可以看出这个内斯特迪尔接收父级传来的嵌套的数组类型的数据,并且它的内部点击新增目录、新增文件,可以触发父级监听的变化事件。比较特殊的是这个组件中调用了自己:
嵌套目录v-if= El。 children :nested= El。儿童/
不过要注意的是调用自己的时候我们并没有在它上面监听它内部传来的change事件,这也是导致二级目录点击新增按钮无效的原因。
我们传递给它的 nested 数据结构大概是下面的样子:
[{
id: 1,
姓名: 目录1,
键入: dir ,
孩子:[{
id: 2,
姓名: 目录3,
键入: dir ,
孩子:[],
pid: 1
}, {
id: 3,
姓名: 文件2,
类型:文件,
pid: 1
}]
}, {
id: 4,
姓名: 目录2,
键入: dir ,
儿童:[]人
}, {
id: 5,
姓名: 文件1,
类型:文件,
儿童:[]人
}]
父组件中调用 NestedDir:
!- directory.vue -
模板
div style= width:50%;方框阴影:0 0 4px 2px rgba(0,0,0,1);边距:10px自动;下填充: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
!-嵌套组件-
nested dir:nested= catalog @ change= handle change /
!-新增弹出框-
El-dialog:title= title :可见。sync= dialogFormVisible width= 300 px
el-form :model=form
El-表单-项目标签=名称
El-input v-model= form。name autocomplete= off /El-input
/El-表单-项目
/el格式
div slot=footer class=对话框-页脚
El-button @ click= dialogFormVisible=false 取消/el-button
El-button type= primary @ click= confirm 确定/el-button
/div
/el-dialog
/div
/模板
脚本
从""导入内斯特迪尔./nested dir ;
导出默认值{
名称:"目录",
组件:{
内斯特迪尔
},
已创建(){
this.catalog=this.getTree()
},
计算值:{
maxId() {
返回this.arr.lastIndex 2
},
topNodes() {
this.arr.forEach(item={
如果(项。儿童)项目。儿童=[]
})
返回this.arr.filter(item=!item.pid)
}
},
data() {
返回{
arr: [
{id: 1,姓名: 目录1 ,类型: dir ,子级:[]},
{id: 2,姓名: 目录3 ,类型:目录,子级:[],pid: 1},
{id: 3,姓名: 文件2 ,类型:"文件",pid: 1},
{id: 4,姓名: 目录2 ,类型: dir ,子级:[]},
{id: 5,姓名: 文件1 ,类型:文件 },
],
标题: ,
dialogFormVisible: false,
表单:{
id: ,
名称: ,
类型: ,
pid:" "
},
目录:[]
}
},
方法:{
handleChange(el) {
this.showDialog(el)
},
确认(){
this.arr.push({.this.form})
this.dialogFormVisible=false
this.catalog=this.getTree()
this.form={
id: ,
名称: ,
类型: ,
pid: ,//父级的编号
}
},
showDialog(el) {
if (el.type===dir) {
this.title=新增目录
this.form.children=[]
this.form.type=dir
}否则{
this.title=新增文件
this.form.type=file
}
if (el.id) {
this.form.pid=el.id
this.form.id=this.maxId
}否则{
this.form.id=this.maxId
}
this.dialogFormVisible=true
},
getTree() {
this.topNodes.forEach(node={
this.getChildren(this.arr,node.children,node.id)
})
返回this.topNodes
},
getChildren(数据,结果,pid) {
对于(字母数据项){
if (item.pid===pid) {
const newItem={.item,children: []}
result.push(newItem)
this.getChildren(data,newItem.children,item.id)
}
}
}
}
}
/脚本
样式范围。btn_group {
填充:20像素10像素
背景色:rgba(87,129,189,0.13);
}
/风格
渲染出的页面是下面的样子:
深层递归组件事件丢失
我们构造出了一个理论上可以无限嵌套的目录结构,但是经过测试发现在二级目录上的新增按钮点击是没有任何反应的,原因是我们在内斯特迪尔中调用了它自己并没有监听内部的变化事件(上边提到过),所以它无法触发父级的-父级的监听事件。
如何解决?
在递归调用的时候也监听一下变化事件,并间接传递到最外层组件(这个是最容易想到的方法,但是如果组件嵌套很深,简直就是个噩梦)EventBus(事件总线)
EventBus
什么事EventBus?
它其实就是一个某视频剪辑软件实例,有$emit 、$on 、$off方法,允许从一个组件向另一组件传递数据,而不需要借助父组件。具体做法是在一个组件$emit,在另一个组件$on,可以像下面这样做:
//main.js
从“vue”导入某视频剪辑软件
从导入应用程序 App.vue
export const事件bus=new Vue();//创建事件总线。
新Vue({
render: h=h(App),
}).$ mount("# app ")
这样我们来改造一下directory.vue,只需要改动srcipt部分:
脚本
从""导入内斯特迪尔./nested dir ;
从导入{事件总线}./main ;
导出默认值{
名称:"目录",
组件:{
内斯特迪尔
},
已创建(){
this.catalog=this.getTree()
事件总线.$on(更改,函数(数据){
//todo向之前一样处理即可
})
},
销毁(){
事件总线.$off(更改)
},
计算值:{
maxId() {
返回this.arr.lastIndex 2
}
},
data() {
返回{
arr: [
{id: 1,姓名: 目录1 ,类型: dir ,子级:[]},
{id: 2,姓名: 目录3 ,类型:目录,子级:[],pid: 1},
{id: 3,姓名: 文件2 ,类型:"文件",pid: 1},
{id: 4,姓名: 目录2 ,类型: dir ,子级:[]},
{id: 5,姓名: 文件1 ,类型:文件 },
],
标题: ,
dialogFormVisible: false,
表单:{
id: ,
名称: ,
类型: ,
pid:" "
},
目录:[]
}
},
方法:{
handleChange(el) {
this.showDialog(el)
},
确认(){
this.arr.push({.this.form})
this.dialogFormVisible=false
this.catalog=this.getTree()
this.form={
id: ,
名称: ,
类型: ,
pid: ,//父级的编号
}
},
showDialog(el) {
if (el.type===dir) {
this.title=新增目录
this.form.children=[]
this.form.type=dir
}否则{
this.title=新增文件
this.form.type=file
}
if (el.id) {
this.form.pid=el.id
this.form.id=this.maxId
}否则{
this.form.id=this.maxId
}
this.dialogFormVisible=true
},
getTree() {
this.topNodes.forEach(node={
this.getChildren(this.arr,node.children,node.id)
})
返回this.topNodes
},
getChildren(数据,结果,pid) {
对于(字母数据项){
if (item.pid===pid) {
const newItem={.item,children: []}
result.push(newItem)
this.getChildren(data,newItem.children,item.id)
}
}
}
}
}
/脚本
引入了从导入{事件总线}./main ;
在页面创建时加入事件监听,销毁时移除事件监听:
已创建(){
事件总线.$on(更改,函数(数据){
this.handleChange(数据)
})
},
销毁(){
事件总线.$off(更改)
}
内斯特迪尔中也需要做相应改动,只需要修改方法中的增加方法:
从导入{事件总线}./main ;
//.略
方法:{
添加(el) {
//这个emit(change ,el)
事件总线.$emit(change ,el)
}
}
这样点击二级目录的新增按钮,就可以正常触发弹出框了。
上面的事件总线只在Vue2中有效,Vue3中已经移除了$开,$关这些方法,所以下一篇文章打算自己做一个某视频剪辑软件的插件来处理这种类似于发布/订阅的情况。
到此这篇关于某视频剪辑软件嵌套组件传参实例分享的文章就介绍到这了,更多相关某视频剪辑软件嵌套组件传参内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。