1、JS相关
1.1 判断两个数组的内容是否相等
mounted() {
const array1 = ["pink", "blue", "green", "pink", 1, '1', '11', 11];
const array2 = ["green", '1', 1, "pink", "blue", '11', 11, "pink"];
const flag = this.areArraysContentEqual3(array1, array2)
console.log('flag--', flag);
},
methods: {
areArraysContentEqual3(arr1= [], arr2 = []) {
if (arr1.length !== arr2.length) {
return false;
}
const countMap = new Map();
console.log('countMap11111--', countMap);
// 计数第一个数组的元素
for (const item of arr1) {
countMap.set(item, (countMap.get(item) || 0) + 1);
console.log('countMap.get(item)--', countMap.get(item));
}
console.log('countMap22222--', countMap);
// 比较第二个数组与计数
for (const item of arr2) {
const val = countMap.get(item);
if (val === undefined || val <= 0) {
return false;
}
countMap.set(item, val - 1);
}
console.log('countMap33333--', countMap);
return true;
},
}
1.2 空合并运算符 ??
定义:当左边操作数为
null
或undefined
时,则取右边操作数的值,否则取左边操作数的值。
举例:
// 举例1:
const a = null
const result = a ?? 'test' // 意思是:a的值为null,则 result='test'
// 举例2:
const b = 0
const result = b ?? 'test' // 意思是:b的值为0,不为null或undefined,那么result的值为b的值,即 result = 0
运算符?? 和 运算符|| 有些类似,但又有所不同,区别在于:
??:判断左边变量是否为null
、undefined
;
||:判断左边变量是否为false
,包括布尔值false、空字符串’'、0;
// 逻辑运算符??
const a = undefined
const result = a ?? 'test' // 由于 a = undefined,所以 result = 'test'
// 逻辑运算符||
const b = false
const result = b || 'test-b' // 由于 b = false,所以 result = 'test-b'
1.3 字符串转数字类型
可以使用parseInt()、parseFloat()、Number()、运算符+。
举例
let a = parseInt('99');
let b = parseFloat('123.45');
let c = Number('66');
let d = Number('66.6');
let f = +'88'
let g = +'3.14'
1.4 flat() 方法
定义:flat() 方法方法会按照一个可指定的深度,递归遍历数组,并将所有元素与遍历到的子数组中的元素,合并为一个新数组返回。
语法:flat(depth)。depth为指定要提取嵌套数组的结构深度,默认值为 1
。depth为Infinity
时,可展开任意深度的嵌套数组。
- flat() 方法会移除数组中的空项
举例
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// flat() 方法会移除数组中的空项
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]
1.5 reduce()方法
定义:reduce()方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。reduce() 对于空数组是不会执行回调函数的。
语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
2个参数:第一个参数为回调函数,第二个为初始值。如果不给入初始值则会以数组第一项为初始值!
回调函数中又有4个参数:
total
: 初始值 或者 计算结束后的返回值, 必须要传。currentValue
:当前元素,必须要传。currentIndex
:当前元素的索引,可选。arr
:当前元素所属的数组对象,可选。
- 使用举例
累加
// 普通数组累加 let arr = [1, 2, 3, 4, 5] let sum = arr.reduce((total, currentValue, currentIndex, arr) => total + currentValue); // 结果为15 // 数组中对象值累加 let arr = [{x:1},{x:2},{x:3}] // total+current.x : 使用 arr 数组的 属性x 的值 进行累加。total 初始值为0 let sum = arr.reduce(function(total,current){ return total+current.x },0)
数组去重
let arr = [1, 9, 2, 5, 9, 3, 1] let newArr = arr.reduce((total, currentValue, currentIndex) => { if(total.indexOf(currentValue) === -1) { // 这个括号中的条件判断也可以写 !total.includes(current) return total.concat(currentValue) } else { return total } }, [])
扁平化嵌套数组
// 将二维数组转换成一维数组 let arr = [[1,2],[3,4],[5,6]]; let newArr = arr.reduce((total,current)=>{ return total.concat(current) },[]); console.log(newArr ) // [1, 2, 3, 4, 5, 6] // 数组嵌套多层 let arr = [1, [2], [[3], [4]], [[[5], [6]]]] let newArr = [] let deep = 3 // deep要大于0 if(deep > 0) { newArr = arr.reduce((total, current) => { // Array.isArray()判断传入的对象或值是否是一个数组 let value = Array.isArray(current) ? flat(current, deep -1) : [] return total.concat(value) }, []) } console.log(newArr ) // [1, 2, 3, 4, 5, 6] // reduce() + 递归 const arr5 = [1,2,[3,[4,5]], [6,[7]], 8] function getFlatArr (list) { return list.reduce((pre, item) => pre.concat(Array.isArray(item)? getFlatArr(item): item), []) } console.log(getFlatArr(arr5)) // [1, 2, 3, 4, 5, 6, 7, 8]
计算数组中每个元素出现的次数
let arr = ['张三', '李四', '王五', '王五', '张三', '王五', '李四', '张三'] let num = arr.reduce((total, current) => { // 判断current是否在total中 if(current in total) { total[current]++ } else { total[current] = 1 } return total }, {}) console.log(num) // {张三: 3, 李四: 2, 王五: 3}
按属性对Object分类
(使用数组内部每项的某个key对应的值,做为最终生成对象的key,数组当前项为最终生成对象的值)let arr = [ {name: '张三', age: 19}, {name: '李四', age: 20}, {name: '王五', age: 18}, ] let str = 'name' let res = arr.reduce((total, current) => { // //每次循环拿到的对象,只需用到 name的值来分类,作为total的键名 let key = current[str] // 当前name作为键名 //先给total的键名为key 赋value值 ,用数组存value,首为空数组,只有它是数组才能用push if(!total[key]) { total[key] = [] } total[key].push(current) }, {}) console.log(res) 打印结果: { "张三": [{"name": "张三", "age": 19}], "李四": [{"name": "李四", "age": 20}], "王五": [{ "name": "王五", "age": 18}] }
按顺序运行Promise
//函数组成数组const arrPro = [pro1,pro2,fun,pro4] run(arrPro,10).then(console.log)//返回的promise对象成功态resolve(360) then打印 function run(arr,input){ return arr.reduce( //[pro1,pro2,fun,pro4] 循环的第一个currentfun 是函数pro1,也就是第一次: //Promise.resolve(10).then(pro1) :把10 传到pro1中,返回promise对象,把10*1.5=15 resolve //第二次:Promise.resolve(15).then(pro2) :把15传到 pro2 ,返回promise对象。 15*2 = 30 //第三次:Promise.resolve(30).then(fun) 把30 传到fun ,30*3=90,被wrapped成promise返回 //第四次:Promise.resolve(90).then(pro4)把90 传到pro4,90*4=360,返回promise对象 (prom,currentfun)=> prom.then(currentfun), //初始值是promise对象 成功态 Promise.resolve(input) ); } function pro1(a){ return new Promise((resolve,reject)=>{ resolve(a*1.5) }) } function pro2(a){ return new Promise((resolve,reject)=>{ resolve(a*2) }) } function fun(a){ return a*3; } function pro4(a){ return new Promise((resolve,reject)=>{ resolve(a*4) }) }
删除数组中的多个元素
let arr = [1, 2, 3, 4, 5, 6, 7]; let list = [] const removeData = (rowIndex) => { if(Array.isArray(rowIndex)){ list = arr.reduce((total, current, currentIndex) => { console.log(total, current, currentIndex); if (!rowIndex.includes(currentIndex)) { total.push(current) } return total }, []) } } removeData([1,4]); console.log(list); // 结果:[1, 3, 4, 6, 7]
1.6 数值小数点保留位数、四舍五入、不四舍五入
- 保留2位小数且不四舍五入。先将num乘以100,得到314.159,然后使用Math.floor()方法向下取整,得到314,最后除以100,得到3.14
let num = 3.14159;
let n = 100; // 保留两位小数,n为100
let newNum = Math.floor(num * n) / n; // 3.14
- 保留2位小数且四舍五入
let num = 3.14159;
let newNum = num.toFixed(2); // 3.14
2、css相关
2.1 实现八卦图
代码实现:
第一步:
<template>
<div class="wrapper"></div>
</template>
<script>
export default {
name: 'testDemo'
}
</script>
<style lang="scss" scoped>
.wrapper {
width: 204px;
height: 204px;
border: 2px solid black;
background-image: linear-gradient(to right, #ffffff 0%, #ffffff 50%, #000000 50%); // 渐变背景 一半白 + 一半黑
border-radius: 50%;
position: relative;
margin: 20px auto;
}
</style>
第二步:
<template>
<div class="wrapper"></div>
</template>
<script>
export default {
name: 'testDemo'
}
</script>
<style lang="scss" scoped>
.wrapper {
width: 204px;
height: 204px;
border: 2px solid black;
background-image: linear-gradient(to right, #ffffff 0%, #ffffff 50%, #000000 50%); // 渐变背景 一半白 + 一半黑
border-radius: 50%;
position: relative;
margin: 20px auto;
&::before { // 实现 一个黑色圆(上) + 一个白色圆(下)
content: ' ';
display: block;
width: 100px;
height: 100px;
position: absolute;
left: 50px;
top: 0;
background: #000000;
border-radius: 50%;
box-shadow: 0 100px 0 0 #ffffff;
}
}
</style>
第三步:
<template>
<div class="wrapper"></div>
</template>
<script>
export default {
name: 'testDemo'
}
</script>
<style lang="scss" scoped>
.wrapper {
width: 204px;
height: 204px;
border: 2px solid black;
background-image: linear-gradient(to right, #ffffff 0%, #ffffff 50%, #000000 50%); // 渐变背景 一半白 + 一半黑
border-radius: 50%;
position: relative;
margin: 20px auto;
&::before { // 实现 一个黑色圆(上) + 一个白色圆(下)
content: ' ';
display: block;
width: 100px;
height: 100px;
position: absolute;
left: 50px;
top: 0;
background: #000000;
border-radius: 50%;
box-shadow: 0 100px 0 0 #ffffff;
}
&::after { // 实现 白色圆点(上) + 黑色圆点(下)
content: ' ';
display: block;
width: 30px;
height: 30px;
position: absolute;
left: 85px;
bottom: 35px;
background: #000000; // 黑色圆点
border-radius: 50%;
box-shadow: 0 -100px 0 0 #ffffff; // 实现白色圆点
}
}
</style>
2.2 CSS3属性: Clip-Path
定义:clip-path 属性使用裁剪方式创建元素的可显示区域。区域内的部分则显示,区域外的则隐藏。可以指定一些特定形状。
常用方法:
- circle():创建一个圆形裁剪区域。参数是半径和圆心的坐标。circle()函数接受两个参数:半径值和关键字at,紧随其后的是原点位置。半径值可以使用像素(px)或百分比(%)。
clip-path: circle(50% at 100% 100%);
- ellipse():创建一个椭圆形裁剪区域。参数是横轴和纵轴的半径以及圆心的坐标。ellipse()函数接受三个参数:长轴半径、短轴半径和原点位置。
clip-path: ellipse(50% 50% at 100% 100%);
- polygon():创建一个多边形裁剪区域。参数是构成多边形的顶点坐标。
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
- path():使用 SVG 路径来定义裁剪区域。参数是路径的字符串表示形式。
clip-path: path('M 10,10 L190,10 L190,90 L10,90 Z');
- inset(): 内矩形(包括圆角矩形) 。
shape-outside: inset(10px 20px 30px 40px round 10px);
inset(10% 20% round 5px);
2.3 梯形圆角tab
实现代码:
<template>
<div class="wrapper">
<div class="list">
<div
v-for="(item, index) in 5"
:key="index"
class="item"
:class="active === index ? 'active' : 'default'"
@click="active = index"
>
<div>内容-{{index}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'testDemo',
data() {
return {
active: 0,
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
$tab-height: 52px;
$primary-color: 'blue';
$active-color: #ffffff;
$default-color: #e2e8f8;
.wrapper {
margin: 20px;
height: 100%;
border-radius: 12px;
background: #fff;
}
.list {
display: flex;
position: relative;
z-index: 2;
border-radius: 12px 12px 0 0;
background-color: $default-color;
overflow: hidden;
.item {
flex: 1;
height: $tab-height;
display: flex;
justify-content: center;
align-items: center;
font-size: 15px;
color: $primary-color;
font-weight: 600;
position: relative;
&:hover {
cursor: pointer;
}
}
.active {
opacity: 1;
background: #ffffff;
border-radius: 12px 12px 0 0;
box-shadow: 24px 40px 0 $active-color, -24px 40px 0 0 $active-color; // 右边阴影,左边阴影
}
.active::before {
content: '';
position: absolute;
left: -6px;
bottom: 0;
width: 12px;
height: $tab-height;
border-top-left-radius: 12px;
background-color: $active-color;
transform: skewX(-15deg); // 折叠效果, 让奇数项元素整体在X轴上偏移-15度
}
.active::after {
content: '';
position: absolute;
right: -6px;
bottom: 0;
width: 12px;
height: $tab-height;
border-top-right-radius: 12px;
background-color: $active-color;
transform: skewX(15deg); // 让奇数项元素整体在X轴上偏移15度
}
.default::before {
content: '';
position: absolute;
left: 6px;
bottom: 0;
width: 12px;
height: $tab-height;
background: $default-color;
border-bottom-left-radius: 12px;
transform: skewX(15deg);
}
.default::after {
content: '';
position: absolute;
z-index: 1;
right: 6px;
bottom: 0;
width: 12px;
height: $tab-height;
background: $default-color;
border-bottom-right-radius: 12px;
transform: skewX(-15deg);
}
}
</style>
2.3 BFC(block format context 块级计格式化上下文)
含义:
- BFC是块级格式化上下文,是一个独立的布局还款,是页面中的一个渲染区域,可以当作是隔离的容器,容器里的元素在布局上不会影响外部元素的布局,并且可以包含浮动元素,防止浮动对兄弟或父容器造成影响。
具备BFC的元素一般包含这些属性之一(形成BFC的条件):
条件 | 描述 |
---|---|
overflow不为visible | overflow为auto、hidden、scroll时,会生成一个新的BFC,以便处理溢出内容或清除浮动等布局问题 |
float不为none | float为left、right,会创建一个新的BFC |
position为absolute、fixed,且z-index不是auto | 绝对定位元素(position: absolute或position: fixed)若其z-index值被显式设置(非auto),也会创建一个 BFC。 |
display:flex | 弹性布局容器(display: flex)会为其子元素创建一个新的 BFC。 |
display:inline-block | 通过将元素的display属性设置为inline-block,可以使其创建一个新的 BFC。 |
display:table | |
display:tabel-cell | |
display:grid |
2.4 flex布局
(1)改变布局下元素的顺序
利用order
属性,可以改变元素的顺序,
- 值越小的排在前面,值相等的会按照文档流原始顺序排列;
- order属性值接受任意整数值,可以为负数;
举例:
.parent {
display: flex;
}
.first {
order: 2;/** 这个属性可以改变顺序,值越小的排在前面,值相等的会按照文档流原始顺序排列 */
}