Vue — 组件通信(四)
最后更新于:2022-04-02 08:08:47
[TOC]
>[success] # 编写自己的工具类进行父子传递
文章来自AresnTalkingData 前端架构师,iView 作者 发布在掘金网小册中内容启发整理
如果你有能力有钱请你购买原作者文找那个,尊敬每一个原作者是我们应该做的,不要做代码行业的伸手党
感谢这些大佬的文章,本内容是根据大佬的文章二次整理,用更通俗的理解让初学者也能看懂
~~~
1.准备工作,'iview' 作者喜欢在vue结构目录中创建一个lib文件夹,并且在文件夹中创建一个'utils'
文件专门用来写自己的工具方法,结构目录如下:
│ ├── 'lib' //工具包
│ ├── 'tools.js' // 存放和业务无关工具性质的js代码
│ └── 'util.js' //存放和业务相关工具性质的js代码
2.下面将会做这个五个场景父子传递的工具类:
2.1.由一个组件,向上找到最近的指定组件;
2.2.由一个组件,向上找到所有的指定组件;
2.3.由一个组件,向下找到最近的指定组件;
2.4.由一个组件,向下找到所有指定的组件;
2.5.由一个组件,找到指定组件的兄弟组件。
3.注意这次的工具组件传递的查找方法和'dispatch'不同的,这次是找整个组件,而'dispatch' 是吧某个
方法传递
~~~
>[info] ## 由一个组件,向上找到最近的指定组件 -- findComponentUpward
~~~
1.思路:编写这个函数时候,需要的形参分析,根据需要我们是要找到某个组件的最近的指定的父组件,
因此某个组件肯定是参数之一,指定的父组件就是参数之二
2.利用'dispatch' 思想我们需要去递归,一直找到当前组件的父组件,知道找到和我们需要匹配的组件
,因此需要'$parent',和'$options.name'
~~~
>[danger] ##### 在utils 中正式编写
~~~
1.context 参数代表当前起点,也就当前组件的'this',componentName 就是目标组件的,可以理解成当前'this'
向上的某个父组件或者有可能是他的爷爷组件
2.逻辑 先获取当前组件的'$parent' 和 'componentName' 父组件的名称,然后去循环如果他有父组件,并且
组件没有名字或者名字不等于目标的名字,我们就继续递归循环查找,直到找到返回整个对象
3.'iview' 作者的解释:
3.1.第一个参数一般都是传入 this,即当前组件的上下文(实例)。
4.提醒自己一点:在写代码的时候一定要对某些条件做判断,例如下面的代码中的 'if(parent)' 就可以减收不必要
的操作
~~~
~~~
function findComponentUpward (context, componentName) {
let parent = context.$parent;
let name = parent.$options.name;
while (parent && (!name || [componentName].indexOf(name) < 0)) {
parent = parent.$parent
if(parent) {
name = parent.$options.name
}
}
return parent;
}
export { findComponentUpward };
~~~
>[danger] ##### 使用篇章
* 创建一个test-a 父组件
~~~
~~~
* 组件B 子组件去使用组件a的方法
~~~
~~~
* 子组件B
~~~
~~~
* 子组件中兄弟组件默认不包括自己
~~~
';
组件 B
~~~
>[info] ## 由一个组件,向上找到所有的指定组件 -- findComponentsUpward
~~~
1.findComponentsUpward 场景递归后续研究 做标记
~~~
>[danger] ##### findComponentsUpward
~~~
// 由一个组件,向上找到所有的指定组件
function findComponentsUpward (context, componentName) {
let parents = [];
const parent = context.$parent;
if (parent) {
if (parent.$options.name === componentName) parents.push(parent);
return parents.concat(findComponentsUpward(parent, componentName));
} else {
return [];
}
}
export { findComponentsUpward };
~~~
>[info] ## 由一个组件,向下找到最近的指定组件 -- findComponentDownward
~~~
1.原理就是找到当前组件的所有子组件,然后递归查找看那个子组件符合我们传入的名字
如果相等就是我们需要的组件
2.这里要说明一个数组的循环,for ...in 和 for ...of,in简单粗暴理解循环对象用的k值
,因此循环数组的时候是脚标,of 是用来循环数组中的内容
~~~
>[danger] ##### findComponentDownward
~~~
1.找到当前组件的所有子组件利用'$children',如果子组件中也没有就去子组件的子组件找
,也就是递归查找,知道找到了 返回对应的子组件
2.这里注意循环数组的循环使用 for ...of
~~~
~~~
function findComponentDownward (context,componentName){
let childrens = context.$children
// 定义一个接受 变量
let children = null;
if(childrens.length>0){
for(const child of childrens){
const name = child.$options.name
if(name == componentName) {
children = child
break;
}else{
children = findComponentDownward(child, componentName)
if (children) break;
}
}
}
return children
}
export { findComponentDownward };
~~~
>[danger] ##### 案例
* 父组件A
~~~
组件 B
~~~
>[info] ## 由一个组件,向下找到所有的指定组件 -- findComponentsDownward
~~~
1.findComponentsDownward 场景递归后续研究 做标记
~~~
>[danger] ##### findComponentsUpward
~~~
1.后续理解'reduce' 方法
~~~
~~~
// 由一个组件,向下找到所有指定的组件
function findComponentsDownward (context, componentName) {
return context.$children.reduce((components, child) => {
if (child.$options.name === componentName) components.push(child);
const foundChilds = findComponentsDownward(child, componentName);
return components.concat(foundChilds);
}, []);
}
export { findComponentsDownward };
~~~
>[info] ## 找到指定组件的兄弟组件——findBrothersComponents
~~~
~~~
>[danger] ##### findBrothersComponents
~~~
1.这里使用了三个参数,和之前一样钱两个分别是起始组件对象,要找的组件名字,
这里还用了数组方法'findIndex' 用来找到脚标
2.对第三个参数做详细讲解,第三个参数是,是否包含自己,咋一看觉得无法理解,
举个例子,想弹窗这类组件 在一个页面可能会使用多次,但是她们的名字相同,但是
我在对应的兄弟组件肯定是不想包含本身,因此利用了'_uid' 唯一标识做了标记去重
~~~
~~~
function findBrothersComponents (context,componentName,exceptMe = true) {
// 找到符合的子组件名称数组
let res = context.$parent.$children.filter(item =>{
return item.$options.name === componentName;
})
// 找到当前本身组件在数组中的位置
let index = res.findIndex(item =>{
return item._uid === context._uid
})
if (exceptMe) res.splice(index, 1);
return res;
}
export { findBrothersComponents };
~~~
>[danger] ##### 案例说明
* 父组件中同一个组件调用两次
~~~
组件 B
~~~