记录项目开发过程中遇到的需求和相关问题的解决方案
1. echarts 去掉刷新按钮
项目中,图表展示用的Echarts,在Echarts的数据视图中,有默认的“关闭”、“刷新”两个按钮。点击“刷新”按钮,会自动关闭当前数据视图,体验不好并且对我们的项目没有实际意义。那么如何去掉数据视图中的“刷新”按钮那?
toolbox: {
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true }, //去掉刷新按钮
saveAsImage: { show: true },
},
},
2.echarts 调整图表 位置 的方法
- 内部图表大小是与div容器大小位置相关的,如果想调整图表大小位置,调整div的属性就可以了
- 如果是想调整图表与div间上下左右留白,则设置grid属性就可以了
myChart.setOption({
title:{
text:"价格指数"
},
grid:{
left:'8%',
right :'0',
bottom :'1%',
containLabel:true
},
- 饼图,通过series中的center属性调整。
饼图使用grid属性无法调整,需要使用series中的center属性
3. 全屏效果
先看效果
- 安装这个库
npm install screenfull
导入
import screenfull from 'screenfull'
- 使用方法
3. 关键代码
<div class="cus-topIcon-item" @click="topHandle('screen')">
<i :class="{ 'bi-arrows-fullscreen': !fullscreen, 'bi-fullscreen-exit': fullscreen }" :title="fullscreen == false ? '全屏' : '退出全屏'"></i>
</div>
// 头部菜单栏的操作
topHandle(tag) {
switch (tag) {
case 'screen':
this.toggleFullScreen()
break
default:
break
}
},
// 全屏
toggleFullScreen() {
if (!screenfull.isEnabled) {
this.$notify({
title: '温馨提示',
message: '您的浏览器无法使用全屏功能,请更换谷歌浏览器或者请手动点击F11按钮全屏展示!',
})
return false
}
screenfull.toggle()
if (screenfull.isFullscreen) {
this.fullscreen = false
} else {
this.fullscreen = true
}
},
4. tab下划线过渡动画
- 先看效果
2. 因为需要根据每一个路由的切换来添加下划线,可以在路由的
meta
中配置额外信息,来控制添加。(ps:第一次想的方法,不合适,可以看下面优化的)
补充:样式
3.transition实现补间动画(过渡效果)
并且当前元素只要有“属性”发生变化时即存在两种状态(我们用A和B代指),就可以实现平滑的过渡。
- transition: 要过渡的属性 花费时间 运动曲线 何时开始;
- 如果有多组属性变化,还是用逗号隔开 :transition:width .4s ease 0s, height .4s;;
- 如果所有属性都是同样的变化,那么只需要用all 就可以了:transition:all .4s
- 综合案例(其他的看不懂,直接看这个)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录</title>
<!-- <script src="js/vue.js"></script> -->
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f4f4f4;
}
.login_panel {
width: 400px;
height: 300px;
background-color: #fff;
margin: 0 auto;
border-radius: 20px;
box-shadow: 0px 0px 10px #e8e8e8;
position: relative;
overflow: hidden;
}
h2 {
text-align: center;
padding: 10px;
}
h2 img {
width: 40px;
vertical-align: bottom;
}
.tab {
height: 40px;
line-height: 40px;
text-align: center;
margin-bottom: 0px;
cursor: pointer;
}
.tab a {
width: 130px;
display: inline-block;
}
.input_style {
width: 350px;
height: 50px;
padding-left: 15px;
margin-left: 15px;
margin-bottom: 10px;
outline: none;
border: none;
background-color: #f7f7f7;
border-radius: 10px;
position: relative;
}
.input_style:focus {
border: 1px solid #8EC5FC;
/* #8EC5FC */
}
.btn_login {
width: 350px;
height: 50px;
border-radius: 10px;
border: none;
outline: none;
margin-left: 15px;
margin-top: 20px;
color: #fff;
font-size: 18px;
background-image: linear-gradient(#ABDCFF, #0396FF);
}
.getCode_style {
position: absolute;
right: 30px;
top: 170px;
width: 90px;
height: 30px;
color: #0396FF;
border: 1px solid #ABDCFF;
text-align: center;
line-height: 30px;
border-radius: 10px;
cursor: pointer;
}
.img_login_img {
margin-left: 130px;
}
.img_login_p {
margin-left: 120px;
}
.firstLine {
width: 130px;
height: 3px;
background-color: #0396FF;
display: inline-block;
margin: 0;
padding: 0;
position: relative;
left: 10px;
top: -15px;
transition: all 0.5s;
}
</style>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.js"></script>
<div id="app" class="loginBox">
<h2><img src="img/weiguang_img.png">微光登录</h2>
<div class="login_panel">
<!-- tab栏目 -->
<div class="tab">
<!-- show点击后当前的值,index是下标,两个相等表示两者对应 -->
<a
v-for="(item,index) in list"
@click="show_index(index)"
:class="{'tab_current':show == index}"
>{{item.name}}</a>
</div>
<!-- 线条 -->
<div
class="firstLine"
:style="{left:tryme}"
></div>
<transition
enter-active-class="animated fadeIn"
leave-active-class="animated fadeOut"
mode="out-in"
>
<component :is="componentName"></component> <!-- 取代三个模版 -->
</transition>
</div>
</div>
<!-- 帐号登录组件 -->
<template id="zhanghaoTmp">
<div>
<p>
<input type="text id="user placeholder="请输入账号"
class="input_style"
>
</p>
<p>
<input
type="text"
id="pwd"
placeholder="请输入密码"
class="input_style"
>
</p>
<button class="btn_login">登 录</button>
</div>
</template>
<!-- 手机号码组件 -->
<template id="telLoginTmp">
<div>
<p>
<input
type="text"
id="tel"
placeholder="请输入手机号码"
class="input_style"
>
</p>
<p>
<input
type="text"
id="code"
placeholder="请输入验证码"
class="input_style"
>
<a class="getCode_style">获取验证码</a>
</p>
<button class="btn_login">登 录</button>
</div>
</template>
<!-- 二维码组件 -->
<template id="codeLoginTmp">
<div>
<img
src="img/code.PNG"
class="img_login_img"
>
<p class="img_login_p">请使用微光APP扫码登录</p>
</div>
</template>
<script>
Vue.component('zhanghang-login', {
template: '#zhanghaoTmp'
})
Vue.component('tel-login', {
template: '#telLoginTmp'
})
Vue.component('code-login', {
template: '#codeLoginTmp'
})
var vm = new Vue({
el: '#app',
data: {
show: 0,
list: [{ name: '账号登录' }, { name: '短信登录' }, { name: '扫码登录' }],
componentName: 'zhanghang-login'
},
computed: {
tryme () {
return (10 + this.show * 130) + 'px'
}
},
methods: {
show_index (index) {
this.show = index;
if (this.show == 0) {
this.componentName = 'zhanghang-login'
} else if (this.show == 1) {
this.componentName = 'tel-login'
} else {
this.componentName = 'code-login'
}
}
}
})
</script>
</body>
</html>
4.1优化代码,好用
offsetLeft 定义和用法
offsetLeft 是一个只读属性,返回当前元素相对于 offsetParent 节点左边界的偏移像素值。
返回值包含:
- 元素向左偏移的像素值,元素的外边距(margin)
- offsetParent 元素的左侧内边距(padding)、边框(border)及滚动条
注意: offsetParent 元素是一个指向最近的(指包含层级上的最近)包含该元素的定位元素或者最近的元素。
提示: 获取元素顶部的偏移量使用 offsetTop 属性。
<template>
<div>
<div class="menu-container">
<div v-for="(item, index) in menuArr" :key="index" class="menu-item" @click="menuItemHandle($event, item)">{{ item }}</div>
<div class="menu-line" :style="meunLineConfig"></div>
</div>
{{ meunLineConfig }}
</div>
</template>
<script>
export default {
name: '',
data: () => {
return {
menuArr: ['测试菜单栏', '测试dasfsdhflk sjf栏', '测试顶栏', '菜单栏+++', '菜单栏菜单栏'],
meunLineConfig: {
left: '0px',
width: '10px',
},
}
},
methods: {
menuItemHandle(event, item) {
console.log(event, item)
console.log(event.target.offsetWidth)
this.meunLineConfig.left = event.target.offsetLeft + 'px'
this.meunLineConfig.width = event.target.offsetWidth + 'px'
console.log(this.meunLineConfig)
},
},
}
</script>
<style lang="scss" scoped>
.menu-container {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
padding: 0 20px;
height: 60px;
background: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 2px;
box-sizing: border-box;
position: relative;
}
.menu-container .menu-item {
height: 100%;
line-height: 60px;
background: #fff;
border-radius: 2px;
font-size: 20px;
padding: 0 20px;
cursor: pointer;
border: 1px solid;
}
.menu-line {
border-bottom: 2px solid #e21717;
position: absolute;
bottom: 0;
transition: 0.3s;
}
</style>
5. 滚动条开发
效果
overflow
一共有5个属性。
1、overflow
:auto
;内容会被修剪,超出设置的宽高后会出现滚动条
2、overflow:scroll
;内容会被修剪,不管内容是否超出,都会出现滚动条的位置
3、overflow:visible
;这个是默认值,内容不会被修剪,会出现在元素框外面。
4、overflow:hidden
;内容被修剪,多余的内容被隐藏
5、overflow:inherit
;从父元素那里继承overflow的值。
直接看看案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=00, initial-scale=1.0" >
<title>Document</title>
<style>
.container {
margin-left: 400px;
width: 400px;
height: 500px;
display: flex;
flex-direction: column;
background-color: #d3cfcf;
overflow: auto;
}
.item {
/* flex: 1; */
height: 50px;
line-height: 50px;
}
.a {
background-color: pink;
}
.b {
background-color: orange;
}
.c {
background-color: aliceblue;
}
::-webkit-scrollbar-track-piece {
background-color: #fff;
/* 滚动条的背景颜色 */
-webkit-border-radius: 0;
/* 滚动条的圆角宽度 */
}
::-webkit-scrollbar {
width: 8px;
/* 滚动条的宽度 */
height: 8px;
/* 滚动条的高度 */
}
::-webkit-scrollbar-thumb:vertical {
/* 垂直滚动条的样式 */
height: 50px;
background-color: #999;
-webkit-border-radius: 4px;
outline: 2px solid #fff;
outline-offset: -2px;
border: 2px solid #fff;
}
::-webkit-scrollbar-thumb:hover {
/* 滚动条的hover样式 */
height: 50px;
background-color: #9f9f9f;
-webkit-border-radius: 4px;
}
::-webkit-scrollbar-thumb:horizontal {
/* 水平滚动条的样式 */
width: 5px;
background-color: #CCCCCC;
-webkit-border-radius: 6px;
}
</style>
</head>
<body>
<div class="container">
<div class="item a"> 1</div>
<div class="item b">2</div>
<div class="item c">3</div>
<div class="item">ee</div>
<div class="item">e</div>
<div class="item">e</div>
<div class="item">e</div>
<div class="item">e</div>
<div class="item">e</div>
<div class="item">e</div>
<div class="item">e</div>
<div class="item">e</div>
<div class="item">e</div>
</div>
</body>
</html>
6. el-table 行、列合并
- 行合并
<template>
<div>
<el-table :data="tableData" :span-method="objectSpanMethod" border>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="num" label="序号" width="180"></el-table-column>
<el-table-column prop="address" label="地址" width="180"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "elementTest",
data() {
return {
tableData: [
{ name: "zhang", num: 11, address: "北京" },
{ name: "zhang", num: 12, address: "郑州" },
{ name: "zhang", num: 13, address: "开封" },
{ name: "wang", num: 21, address: "日照" },
{ name: "wang", num: 11, address: "烟台" },
{ name: "li", num: 31, address: "石家庄" },
{ name: "li", num: 32, address: "保定" },
{ name: "li", num: 33, address: "唐山" },
{ name: "li", num: 34, address: "秦皇岛" },
],
spanArray: [],
pos: 0, // pos为spanArray的索引
};
},
created() {
this.init(this.tableData);
},
methods: {
init(data) {
for (let i = 0; i < data.length; i++) {
if (i === 0) {
// 如果是第一条记录 向数组里面加入1 并设置索引位置
this.spanArray.push(1);
this.pos = 0;
} else {
// 从第二条数据开始 判断它与前一条记录是否相等
if (data[i].name === data[i - 1].name) {
// 如果相等 将前一位元素+1 表示合并行数+1 同时向spanArr中添加元素0
// 0 表示该行不显示
this.spanArray[this.pos] += 1;
this.spanArray.push(0);
} else {
// 如果不相等 向spanArr中添加元素1 同时改变索引
this.spanArray.push(1);
this.pos = i;
}
}
}
console.log("this.spanArray=====", this.spanArray);
// 打印结果: [3, 0, 0, 2, 0, 4, 0, 0, 0]
},
objectSpanMethod({ rowIndex, columnIndex }) {
// console.log("rowIndex", rowIndex);
// console.log('columnIndex', columnIndex)
// rowIndex 表示行下标,columnIndex 列下标
if (columnIndex === 0) {
let _row = this.spanArray[rowIndex];
let _col = _row > 0 ? 1 : 0;
console.log(`{rowspan: ${_row}, colspan: ${_col}}`);
// 打印结果
// {rowspan: 3, colspan: 1}//表示第1列的1-3行合并
// {rowspan: 0, colspan: 0}
// {rowspan: 0, colspan: 0}
// {rowspan: 2, colspan: 1}//表示第1列的4-5行合并
// {rowspan: 0, colspan: 0}
// {rowspan: 4, colspan: 1}
// {rowspan: 0, colspan: 0}
// {rowspan: 0, colspan: 0}
// {rowspan: 0, colspan: 0}
// {rowspan: 0, colspan: 0} 表示此行不显示
// {rowspan: 2, colspan: 1} 表示跨两行
return {
rowspan: _row,
colspan: _col,
};
}
},
},
};
</script>
- 列合并
<template>
<div>
<el-table :data="tableData6" :span-method="arraySpanMethod" border style="width: 100%" :header-cell-style="headFirst">
<el-table-column prop="id" label="评分项" width="180" align="center">
<el-table-column prop="id" label="ID">
</el-table-column><el-table-column prop="id" label="ID">
</el-table-column>
</el-table-column>
<el-table-column prop="name" label="姓名">
</el-table-column>
<el-table-column prop="amount1" sortable label="数值 1">
</el-table-column>
<el-table-column prop="amount2" sortable label="数值 2">
</el-table-column>
<el-table-column prop="amount3" sortable label="数值 3">
</el-table-column>
</el-table>
<!-- <el-table :data="tableData6" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
<el-table-column prop="id" label="ID" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名">
</el-table-column>
<el-table-column prop="amount1" label="数值 1(元)">
</el-table-column>
<el-table-column prop="amount2" label="数值 2(元)">
</el-table-column>
<el-table-column prop="amount3" label="数值 3(元)">
</el-table-column>
</el-table> -->
</div>
</template>
<script>
export default {
data() {
return {
tableData6: [
{
id: "12987122",
name: "王小虎",
amount1: "234",
amount2: "3.2",
amount3: 10,
},
{
id: "12987123",
name: "王小虎",
amount1: "165",
amount2: "4.43",
amount3: 12,
},
{
id: "12987124",
name: "王小虎",
amount1: "324",
amount2: "1.9",
amount3: 9,
},
{
id: "12987124",
name: "王小虎",
amount1: "324",
amount2: "1.9",
amount3: 9,
},
{
id: "12987124",
name: "王小虎",
amount1: "324",
amount2: "1.9",
amount3: 9,
},
{
id: "12987124",
name: "王小虎",
amount1: "324",
amount2: "1.9",
amount3: 9,
},
],
};
},
methods: {
headFirst({ row, colunm, rowIndex, columnIndex }) {
if (rowIndex === 1) {
//这里为了是将第二行的表头隐藏,就形成了合并表头的效果
return { display: "none" };
}
return "background:#f5f7fa";
},
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
// console.log("row", row);
// console.log("column", column);
// console.log("rowIndex", rowIndex);
// console.log("columnIndex", columnIndex);
if (row.id == "12987122") {
if (columnIndex === 0) {
return [1, 2];//第一行的1-2列合并
} else if (columnIndex === 1) {
return [0, 0];
}
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
}
},
},
};
</script>
首先你要用rowIndex, columnIndex找到要合并的开始单元格,然后接下来的原理是:
- returm {rowspan: 1,colspan: 1}表示表格不变
- return (rowspan: 2,colspan: 1}表示表格向下合并一个单元格
- return {rowspan: 1,colspan: 2}表示表格向右合并一个单元格
- returm (rowspan: 0,colspan: 0}表示删除此单元格
7. js判断当前时间是否在一个时间范围内
beginDateStr是开始时间,endDateStr结束时间
/**
* @param date [beginDateStr] [开始时间]
* @param date [endDateStr] [结束时间]
* @return Boolean
*/
var date = {
isDuringDate: function(beginDateStr, endDateStr) {
var curDate = new Date(),
beginDate = new Date(beginDateStr),
endDate = new Date(endDateStr);
if (curDate >= beginDate && curDate <= endDate) {
return true;
}
return false;
},
};
// 默认的
new Date() // Wed Mar 30 2022 00:46:02 GMT+0800 (中国标准时间)
// GMT格式
new Date().toGMTString() // 'Tue, 29 Mar 2022 16:24:09 GMT'
// ISO格式
new Date().toISOString() // '2022-03-29T16:47:26.681Z'
new Date().toDateString() // 'Wed Mar 30 2022'
8.dayjs
下载
npm install dayjs
引入项目
import dayjs from 'dayjs'
dayjs()
1.1 基本使用
1. 解析时间
day.js解析传入的参数,并返回Day.js对象
// 不传参数直接调用 dayjs() 将返回一个包含当前日期和时间的 Day.js 对象。
dayjs()
// 等同于如下调用方式
dayjs(new Date())
// 传入时间字符串
dayjs('2023/08/10')
dayjs('2023-08-10 08:08:08')
dayjs('2018-04-13 19:18:17.040+02:00')
// 传入毫秒时间戳(13位)
dayjs(1318781876406)
// 传入秒时间戳(10位)
dayjs.unix(1318781876)
// 传入Date对象
dayjs(new Date(2023, 8, 1))
通过.isValid()
验证传入的参数是否能被解析成一个时间日期
dayjs('2022-01-33').isValid() // true
dayjs('invalud string').isValid() // false
2. 获取
dayjs
提供了一系列api来从dayjs
对象中得到年月日、时分秒、周等信息。
// 获取年
dayjs().year() // 2023
// 获取月 0-11
dayjs().month() // 7
// 获取月份里的日期 1-31
dayjs().date() // 10
// 获取小时
dayjs().hour()
// 获取分钟
dayjs().minute()
// 获取秒
dayjs().second()
// 获取一周星期几 0(星期天)到6(星期六)
dayjs().day()
3. 格式化
项目中对时间格式化是最常见的场景,dayjs
返回的是dayjs对象,需要通过.format
方法来指定格式化的方式。
dayjs().format() // 2023-08-11T13:48:51+08:00
dayjs().format('YYYY-MM-DD') // 2023-08-11
dayjs().format('YYYY/MM/DD') // 2023/08/11
dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'
// 字符放在方括号中,即可原样返回而不被格式化替换 (例如, [MM])。
dayjs('2019-01-25').format('[YYYYescape] YYYY-MM-DDTHH:mm:ssZ[Z]')
// 'YYYYescape 2019-01-25T00:00:00-02:00Z'
4.差异diff
有时候常常需要知道一个日期距离另一个日期过了多久,以及两个日期之间的差异
// 返回指定单位下两个日期时间之间的差异,默认返回毫秒数,
const date1 = dayjs('2019-01-25')
const date2 = dayjs('2018-06-05')
date1.diff(date2) // 20214000000 默认单位是毫秒
// 等同于传入第二个参数millisecond
date1.diff(date2, '等同于传入第二个参数millisecond') // 20214000000 默认单位是毫秒
// 要获取其他单位下的差异,则在第二个参数传入相应的单位
(day、month、year、week、hour、minute、second、millisecond)
date1.diff(date2, 'day')
date1.diff(date2, 'month')
date1.diff(date2, 'year')
date1.diff(date2, 'week')
date1.diff(date2, 'hour')
date1.diff(date2, 'minute')
date1.diff(date2, 'second')
date1.diff(date2, 'millisecond')
5. 比较
判断两个日期之差
// 默认比较毫秒
dayjs().isBefore('2023-08-11')
dayjs().isAfter('2023-07-11')
dayjs().isSame('2023-07-11')
// 从天开始比较
dayjs().isBefore('2023-08-11', 'day')
dayjs().isAfter('2023-07-11', 'day')
dayjs().isSame('2023-07-11', 'day')
6.更改
有的时候需要增加、减少一定的时间来获取一个新的时间
- 支持day、week、month、year、hour、minute、second等多种时间单位
// 在当前日期增加add
dayjs().add(7, 'day')
dayjs().add(7, 'month')
dayjs().add(7, 'year')
dayjs().add(7, 'hour')
dayjs().add(7, 'minute')
dayjs().add(7, 'second')
// 在当前日期减少subtract
dayjs().subtract(7, 'day')
dayjs().subtract(7, 'month')
dayjs().subtract(7, 'year')
dayjs().subtract(7, 'hour')
dayjs().subtract(7, 'minute')
dayjs().subtract(7, 'second')
1.2 高级操作
dayjs提供了一些插件来实现一些额外的查询和判断操作
1. 获取当前日期是该年的第几天
import dayOfYear from 'dayjs/plugin/dayOfYear'
dayjs.extend(dayOfYear)
// 2023-8-10 是2023年的第 222 天
dayjs().dayOfYear() //222
2. 获取当前日期是该年的第几周
import weekOfYear from 'dayjs/plugin/weekOfYear'
dayjs.extend(weekOfYear)
dayjs('2018-06-27').week() // 26
3. 判断该年是否是闰年
import isLeapYear from 'dayjs/plugin/isLeapYear'
dayjs.extend(isLeapYear)
dayjs().isLeapYear()
4. 判断一个日期是否在其他两个的日期之间
javascript
复制代码
import isBetween from 'dayjs/plugin/isBetween'
dayjs.extend(isBetween)
dayjs().isBetween('2023-08-11','2023-08-12')
5. 判断一个日期是否是今天、昨天、明天
import isToday from 'dayjs/plugin/isToday'
import isTomorrow from 'dayjs/plugin/isTomorrow'
import isYesterday from 'dayjs/plugin/isYesterday'
dayjs.extend(isToday).extend(isYesterday).extend(isTomorrow)
dayjs().isToday() // true
dayjs().add(1, 'day').isTomorrow() // true
dayjs().add(-1, 'day').isYesterday() // true
6. 判断一个日期是否和另一个提供的日期时间相同或在其之后(之前)
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'
dayjs.extend(isSameOrAfter).extend(isSameOrBefore)
// 比较时间
dayjs().isSameOrAfter('2023-08-11')
dayjs().isSameOrBefore('2023-08-11')
// 从月开始比较
dayjs().isSameOrAfter('2023-08-11', 'month')
dayjs().isSameOrBefore('2023-08-11', 'month')
// 从年开始比较
dayjs().isSameOrAfter('2023-08-11', 'year')
dayjs().isSameOrBefore('2023-08-11', 'year')
7. 距今过去多久
通过relativeTime
插件可以获取一个时间距今多久,或距未来某个时间多久
import relativeTime from 'dayjs/plugin/relativeTime'
// 现在到当前实例的相对时间fromNow
dayjs.extend(relativeTime)
dayjs('1999-08-01').fromNow() // 24 years ago
dayjs('1999-08-01').fromNow(true) // 24 years
dayjs('2022-08-01').fromNow() // a year ago
// 某个日期到当前时间的相对时间from
const a = dayjs('2000-01-01')
dayjs('1999-01-01').from(a) // 1 年前
// 当前实例到现在的相对时间 toNow
dayjs('1999-01-01').toNow() // 24 年后
// 某个日期到当前日期的相对时间 to
const a = dayjs('2000-01-01')
dayjs('1999-01-01').to(a) // 1 年后
8.自定义返回的格式
默认情况下返回的“24 years ago”并不是我们想要的返回,我们需要“24年前”或者仅仅返回24,那么就可以通过updateLocale
插件来自定义输出
import updateLocale from 'dayjs/plugin/updateLocale'
dayjs.updateLocale('en', {
relativeTime: {
future: 'in %s',
past: '%s 前',
s: 'a few seconds',
m: 'a minute',
mm: '%d minutes',
h: 'an hour',
hh: '%d hours',
d: 'a 天',
dd: '%d 天',
M: 'a month',
MM: '%d months',
y: '1 年', // 18个月以内返回 一年前
yy: '%d 年' // xx年前
}
})
dayjs.extend(relativeTime)
dayjs('1999-08-01').fromNow() // 24年前
9. vh和100%
height: 100%; 与 height: 100vh; 在 CSS 中有着不同的含义和应用场景。
-
height: 100%; 表示元素的高度将与其父元素的高度相同。但是,要使 height: 100%; 生效,父元素必须具有明确定义的高度。
- 例如固定高度值或相对定位。如果父元素的高度未被明确定义,那么 height: 100%; 将不会生效。
-
height: 100vh; 表示元素的高度将占据视口(浏览器窗口)的高度。无论父元素的高度如何,使用 height: 100vh; 将使元素占据整个视口的高度,这对于实现全屏或类似效果非常有用。
因此,主要区别在于 height: 100%; 是相对于父元素的高度,而 height: 100vh; 是相对于视口的高度。
在实际应用中,如果您想让一个元素占据整个视口的高度,可以使用 height: 100vh;;如果想让一个元素与其父元素等高,可以使用 height: 100%;,前提是父元素具有明确定义的高度
vh/vw
vh
: 相对于视窗的高度, 视窗被均分为100单位的vh;
vw
: 相对于视窗的宽度, 视窗被均分为100单位的vw;
vmax
: 相对于视窗的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax;
vmin
: 相对于视窗的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin;
视区
所指为浏览器内部的可视区域大小,
即window.innerWidth/window.innerHeight
大小,不包含任务栏标题栏以及底部工具栏的浏览器区域大小。
calc
calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,用来指定元素的长度。比如说,你可以使用calc()给元素的border、margin、pading、font-size和width等属性设置动态值。为何说是动态值呢?
- 因为我们使用的表达式来得到的值。不过calc()最大的好处就是用在流体布局上,可以通过calc()计算得到元素的宽度。
calc是 css3提供的一个在css文件中计算值的函数:
- 用于动态计算长度值。
- 需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
- 任何长度值都可以使用calc()函数进行计算;
- calc()函数支持 “+”, “-“, “*”, “/” 运算;
- calc()函数使用标准的数学运算优先级规则;
calc(100vh - 10px) 表示整个浏览器窗口高度减去10px的大小
calc(100vw - 10px) 表示整个浏览器窗口宽度减去10px的大小
一般用来设置流式布局宽高,当然,你可以使用calc()给元素的border、margin、pading、font-size和width等属性设置动态值。
ps:工作中用过的一些知识点,自己记录的笔记和整理来网络上的资源 ,方便以后复习使用。