9月学习笔记-前端知识碎片

安稳与你 提交于 2020-01-01 02:50:18

工作笔记-知识碎片-2019-9

1.Echarts的cursor指向无效

原因:echarts使用canvas画图,使用行内样式设定canvas的cursor:pointer;
解决:使用样式覆盖这个行内样式比如:.echarts canvas{cursor:pointer !important;}

2.轮播图片宽高自适应问题

效果图:
在这里插入图片描述
宽度为自适应屏幕宽度,有最小宽度,高度不管是设为固定px或百分比都会导致图片变形或被裁剪,所以应动态设定图片高度。
html:

	<div class="ty-carousel">
		<el-carousel ref='ctest' :height="imgHeight+'px'" :interval='5000'>
			<el-carousel-item v-for="(item,index) in carouselData" :key="index">
				<img  ref="image" :src="item.src" alt="">
			</el-carousel-item>
		</el-carousel>
	</div>

style:

	.ty-carousel{ margin-bottom: 16px; }
	.ty-carousel .el-carousel__item img {
	    width: 100%;
	    height: auto;
	}

	.ty-carousel .el-carousel__indicators{left: auto; right:0;  }

js:(基于vue框架)

import axios from "axios";
export default{
	data(){
		return{
			imgHeight: "",
			carouselData:[
				{
					src:'/static/static_web/images/ty/Carousel-1.png',
				},{
					src:'/static/static_web/images/ty/Carousel-2.png',
				},{
					src:'/static/static_web/images/ty/Carousel-3.png',
				},{
					src:'/static/static_web/images/ty/Carousel-4.png',
				},
			]
		}
	},
	methods: {
		imgLoad() {
		      this.$nextTick(function() {
		        // 定义页面初始的轮播图高度
		        this.imgHeight = this.$refs.image[0].height
		      });
		},
		getImgUrl() {
		      axios
		        .get("/module_web/MI-SecurityMonitorStrategy2.html")//页面路径
		        .then(res => {
		          // 调用this.imgLoad()方法定义图片初始高度
		          this.imgLoad();
		        })
		        .catch(error => {
		          console.log(error);
		        });
		  }
	},
	mounted() {
		    this.getImgUrl();
		    // 监听窗口变化,使得轮播图高度自适应图片高度
		    window.addEventListener("resize", () => {
		      this.imgHeight = this.$refs.image[0].height;
		    });
	}

}

3.深拷贝与浅拷贝

浅拷贝:只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝
深拷贝:是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝

let obj1= {
	a:1;
	b:123
}
let obj2 = obj1;
obj2.a=2;
console.log(obj2.a);//2
console.log(obj1.a);//2

解构赋值也是浅拷贝
一开始我只是用简单的数组进行测试:

let arr1= [11,22];
let arr2=[...arr1];
arr2[0]=33;

console.log(arr2);//[33,22];
console.log(arr1);//[11,22]

改变拷贝后的数组后,原数组并没有改变我便以为其为深拷贝(深复制);但其实它只是拷贝了浅浅一层,是fake!,是骗子!它是浅拷贝,而不是层层递进的深拷贝:

let arr1= [{a:11},{b:22},44];
let arr2=[...arr1];
arr2[0].a=33;
arr2[2] = 55;

console.log(arr2);// [{a:33},{b:22},55]
console.log(arr1);// [{a:33},{b:22},44]

大概是这样的内存结构:
在这里插入图片描述
明确一下深拷贝与浅拷贝:
浅拷贝
在这里插入图片描述
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

深拷贝
在这里插入图片描述
将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

实现深拷贝

参考https://juejin.im/post/5d6aa4f96fb9a06b112ad5b1

  • 乞丐版
    可以使用parse和stringify进行深拷贝
let arr1 = [{a:11},{b:22},44];
let arr2 = JSON.parse(JSON.stringify(arr1))
arr2[0].a=33;

console.log(arr2);// [{a:33},{b:22},44]
console.log(arr1);// [{a:11},{b:22},44]
  • 基础版
    用递归实现层层递进深拷贝
    缺陷:拷贝其他引用类型、拷贝函数、循环引用等
function clone(target) {
    if (typeof target === 'object') {
        let cloneTarget = {};
        for (const key in target) {
            cloneTarget[key] = clone(target[key]);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

如果是原始类型,无需继续拷贝,直接返回
如果是引用类型,创建一个新的对象,遍历需要克隆的对象,将需要克隆对象的属性执行深拷贝后依次添加到新对象上。
缺陷:没有考虑数组

  • 兼容数组
module.exports = function clone(target) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        for (const key in target) {
            cloneTarget[key] = clone(target[key]);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

  • 考虑循环引用
    解决循环引用问题,我们可以额外开辟一个存储空间,来存储当前对象和拷贝对象的对应关系,当需要拷贝当前对象时,先去存储空间中找,有没有拷贝过这个对象,如果有的话直接返回,如果没有的话继续拷贝,这样就巧妙化解的循环引用的问题。

这个存储空间,需要可以存储key-value形式的数据,且key可以是一个引用类型,我们可以选择Map这种数据结构:

function clone(target, map = new Map()) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        if (map.get(target)) {
            return map.get(target);
        }
        map.set(target, cloneTarget);
        for (const key in target) {
            cloneTarget[key] = clone(target[key], map);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

检查map中有无克隆过的对象
有 - 直接返回
没有 - 将当前对象作为key,克隆对象作为value进行存储
继续克隆

使用WeakMap提代Map来使代码达到画龙点睛的作用:

function clone(target, map = new WeakMap()) {
    // ...
};
  • 性能优化和其他类型考虑可查看参考的文章

4.shift方法

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值

5.函数节流与防抖

对持续触发的事件进行时间频率控制
具体方法参考https://www.jianshu.com/p/c8b86b09daf0
防抖:就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

function debounce(func, wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout);
        
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait);
    }
}

节流:就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。

function throttle(func, wait) {
    let previous = 0;
    return function() {
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}

6.粘性布局

position:sticky

7.强制不换行

white-space:no-wrap

8.截取字符串中指定字符的前后字符串

.split(str)[0].split(str)[1]

9.computed计算属性

set get

10.loadsh

cloneDeep

11.水球图配置

https://github.com/ecomfe/echarts-liquidfill#api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!