高级前端进阶(三)

感谢 遗忘的过路人 这位博主,发现了 高级前端进阶(一) 中的list转树形数据的问题。当然也是我的疏忽。抱歉!!!

一、解决问题

复现一下问题

将list数据不按id顺序排序,将之打乱

// list数据
[
    {
        id: 4, pid: 1, name: "二级数据2-1"
    },
    {
        id: 5, pid: 1, name: "二级数据2-2"
    },
    {
        id: 6, pid: 1, name: "二级数据2-3"
    },
    {
        id: 1, pid: 0, name: "一级数据1"
    },
    {
        id: 2, pid: 0, name: "一级数据2"
    },
    {
        id: 3, pid: 0, name: "一级数据3"
    },
    {
        id: 7, pid: 3, name: "三级数据3-1"
    },
    {
        id: 8, pid: 3, name: "二级数据3-2"
    },
    {
        id: 9, pid: 8, name: "三级数据3-1"
    }
]

使用listToArray方法得到的数据便会出现问题。

解决方法:

listData.sort((a, b) => { return Number(a[idMap]) - Number(b[idMap]) });

对,就是这一行代码。加上这一行代码,便解决了。

引发的思考

之前的方法,只要进行一次遍历即可,然而现在发现,之前的方法的前提是数据已经是排好序的。
如果错乱了呢?那不得不进行一次sort排序。这样的话,不还是两次遍历了吗?(加上了一次sort排序遍历)
再次分析一下原理
我们知道,核心原理就是这个东西 itemMap[id] = item; 将list数据以对象的属性跟值存储,方便获取。
一次遍历的话,给对象itemMap添加属性的同时获取其父亲节点,如果顺序错乱的话,自然就会出现问题了。

二、解析URL中的参数

此方法针对vue项目hash路由模式

// //localhost:9090/#/test/url?id=34&name=%E6%86%A8%E6%86%A8
function getUrlParams() {
    let index = window.location.href.indexOf('?');
    let urlSearchParams = new URLSearchParams(window.location.href.slice(index + 1));
    let params = Object.fromEntries(urlSearchParams.entries());
    return params;
}

三、CSS3过渡跟动画

这两者的区别,很简单,
过渡就是字面上意思,比如,宽度从1px,慢慢增加到10px,这便是一种过渡;
动画,也是字面上意思,不过跟过渡最大的区别就是最终的状态,不管执行了什么动画,最终的状态会还原,比如说宽度从1px,慢慢增加到10px,动画结束后,会还原到1px。

举几个例子,举一反三即可。
1、过渡属性:

transition: width 1s linear 2s;
// 等价于
transition-property: width;
transition-duration: 1s;
transition-timing-function: linear;
transition-delay: 2s;

实例(鼠标悬浮在div上,3秒后,宽度从150px,2秒的时间均匀增长到400px,然后停止)

div {
  width: 150px;
  height: 100px;
  background: blue;
  transition: width 1s linear 3s;
}
div:hover {
  width: 400px;
}

2、动画属性

animation-name: myfirst;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 2s;
animation-iteration-count: infinite;// 动画循环次数,永久
animation-direction: alternate;// 动画一个周期结束后,倒序播放,正常是 normal
animation-play-state: running;
// 等价于
animation: myfirst 5s linear 2s infinite alternate;
// 动画名称的两种写法
@keyframes myName1 {
  from {
    background: red;
  }
  to {
    background: yellow;
  }
}
@keyframes myName2 {
  0% {
    background: red;
  }
  50% {
    background: green;
  }
  100% {
    background: blue;
  }
}

实例(div的背景颜色从红色->绿色->蓝色,蓝色->绿色->红色,无限循环)

div
{
    animation: myfirst2 5s linear 2s infinite alternate;
}

四、事件总线

我们知道JavaScript中的,apply,call,bind的使用及其区别。
有个地方便用到了,就是事件总线。
首先,简述一下原理。
其实很简单的。
先申明一个对象bus,其中的对象用来存储事件名称,其值用来存储需要执行的方法。emit发送事件的时候,给bus添加事件名称跟方法,on则接收事件名,来触发对应的方法。
很简单吧!
代码如下:

class EventBus {
    constructor() {
        this.bus = {};
    }
    $on(busName, fn) {
        if (this.bus.hasOwnProperty(busName)) {
            console.log('该事件名已订阅过');
            return;
        }
        this.bus[busName] = fn;
    }
    $emit(busName, ...args) {
        this.bus[busName].apply(null, args);
    }
    $off(busName) {
        delete this.bus[busName]
    }
}

看完代码,你一定很懵,这,这,这,也太简单了吧!的确是这样。以上就是最简单的事件总线代码。我本人也使用这个,毕竟简单、粗暴。

学习技术要执着,但也不能太执着!