常用工具库详解
dayjs
推荐使用 dayjs,和 moment 用法一致,但打包更小(moment 打包之后 200k,dayjs 打包之后 2k)
官方网站:dayjs 中文教程
安装:npm i dayjs
获取 & 设置
| 单位 | 全拼 | 说明 |
|---|---|---|
| 年 | year | y |
| 月 | month | M(一月 0,十二月 11) |
| 日 | date | D |
| 星期 | day | d(星期天 0,星期六 6) |
| 时 | hour | h |
| 分 | minute | m |
| 秒 | second | s |
| 毫秒 | millisecond | ms |
示例:
- 获取年:
dayjs().year()或dayjs().get('year') - 设置年:
dayjs().year(2000)或dayjs().set('year', 2000)
操作
js
// 格式化
dayjs().format('YYYY-MM-DD hh:mm:ss A') // 2021-01-10 04:39:28 PM
// 获取一月初
dayjs().startOf('month')
// 获取一年年末
dayjs().endOf('year')
// 增加7天
dayjs().add(7, 'days')
// 减少7天
dayjs().subtract(7, 'days')
// 上个月
dayjs().subtract(1, 'months')// 格式化
dayjs().format('YYYY-MM-DD hh:mm:ss A') // 2021-01-10 04:39:28 PM
// 获取一月初
dayjs().startOf('month')
// 获取一年年末
dayjs().endOf('year')
// 增加7天
dayjs().add(7, 'days')
// 减少7天
dayjs().subtract(7, 'days')
// 上个月
dayjs().subtract(1, 'months')startOf / endOf 支持的单位:year(y)、quarter(Q)、month(M)、week(w)、date(D)、day(d)、hour(h)、minute(m)、second(s)
查询
js
dayjs('2010-10-20').isBefore('2010-10-21') // true
dayjs('2010-10-20').isAfter('2010-10-21') // falsedayjs('2010-10-20').isBefore('2010-10-21') // true
dayjs('2010-10-20').isAfter('2010-10-21') // false闰年判断需要插件:
js
var isLeapYear = require('dayjs/plugin/isLeapYear')
dayjs.extend(isLeapYear)
dayjs().isLeapYear()var isLeapYear = require('dayjs/plugin/isLeapYear')
dayjs.extend(isLeapYear)
dayjs().isLeapYear()返回月份的天数:dayjs().daysInMonth()
格式化
js
dayjs().format('YYYY-MM-DD hh:mm:ss') // 2020-05-02 10:30:00dayjs().format('YYYY-MM-DD hh:mm:ss') // 2020-05-02 10:30:00| 占位符 | 输出 | 详情 |
|---|---|---|
YY | 18 | 两位数年份 |
YYYY | 2018 | 四位数年份 |
M | 1-12 | 月份 |
MM | 01-12 | 月份,两位数 |
MMM | Jan-Dec | 缩写月份名称 |
MMMM | January-December | 完整月份名称 |
D | 1-31 | 月份里的一天 |
DD | 01-31 | 两位数 |
d | 0-6 | 星期天是 0 |
H | 0-23 | 小时,24 小时制 |
HH | 00-23 | 小时,两位数 |
h | 1-12 | 小时,12 小时制 |
hh | 01-12 | 两位数 |
m | 0-59 | 分钟 |
mm | 00-59 | 两位数 |
s | 0-59 | 秒 |
ss | 00-59 | 两位数 |
SSS | 000-999 | 毫秒 |
A | AM PM | |
a | am pm |
时长 duration
需要引入插件:
js
import duration from 'dayjs/plugin/duration'
dayjs.extend(duration)
// 获取秒,传入时间戳
dayjs.duration(1500).seconds() // 1import duration from 'dayjs/plugin/duration'
dayjs.extend(duration)
// 获取秒,传入时间戳
dayjs.duration(1500).seconds() // 1Moment.js
Moment.js 是一个用于解析、验证、操作和显示日期和时间的 JavaScript 库
安装:npm install moment
创建日期
js
const now = moment()
const specificDate = moment('2024-12-31')
const ymdDate = moment({ year: 2024, month: 11, day: 31 })const now = moment()
const specificDate = moment('2024-12-31')
const ymdDate = moment({ year: 2024, month: 11, day: 31 })格式化
js
moment().format() // 2024-05-30T09:30:26+00:00
moment().format('YYYY-MM-DD') // 2024-05-30
moment().format('MMMM Do YYYY, h:mm:ss a') // May 30th 2024, 9:30:26 ammoment().format() // 2024-05-30T09:30:26+00:00
moment().format('YYYY-MM-DD') // 2024-05-30
moment().format('MMMM Do YYYY, h:mm:ss a') // May 30th 2024, 9:30:26 am操作
js
moment().add(7, 'days')
moment().subtract(2, 'months')
moment().set('month', 0) // Januarymoment().add(7, 'days')
moment().subtract(2, 'months')
moment().set('month', 0) // January比较
js
moment('2024-12-31').isBefore('2025-01-01') // true
moment('2024-12-31').isAfter('2024-01-01') // true
moment('2024-12-31').isSame('2024-12-31') // truemoment('2024-12-31').isBefore('2025-01-01') // true
moment('2024-12-31').isAfter('2024-01-01') // true
moment('2024-12-31').isSame('2024-12-31') // true差异
js
const end = moment('2024-12-31')
const start = moment('2024-01-01')
end.diff(start, 'days') // 364
end.diff(start, 'months') // 11const end = moment('2024-12-31')
const start = moment('2024-01-01')
end.diff(start, 'days') // 364
end.diff(start, 'months') // 11时区
js
moment().format('Z') // +00:00moment().format('Z') // +00:00需要 moment-timezone 插件:
js
const moment = require('moment-timezone')
moment.tz('2024-12-31 23:59:59', 'America/New_York')const moment = require('moment-timezone')
moment.tz('2024-12-31 23:59:59', 'America/New_York')本地化
js
moment.locale('zh-cn')
moment().format('LLLL') // 2024年5月30日星期四 09:30moment.locale('zh-cn')
moment().format('LLLL') // 2024年5月30日星期四 09:30倒计时示例
js
function countdown(targetTime) {
const intervalId = setInterval(() => {
const now = moment()
const target = moment(targetTime)
const diff = target.diff(now)
if (diff <= 0) {
clearInterval(intervalId)
console.log('0天00时00分00秒')
} else {
const duration = moment.duration(diff)
const formatted = `${Math.floor(duration.asDays())}天${String(duration.hours()).padStart(2, '0')}时${String(duration.minutes()).padStart(2, '0')}分${String(duration.seconds()).padStart(2, '0')}秒`
console.log(formatted)
}
}, 1000)
}
countdown('2024-12-31T23:59:59')function countdown(targetTime) {
const intervalId = setInterval(() => {
const now = moment()
const target = moment(targetTime)
const diff = target.diff(now)
if (diff <= 0) {
clearInterval(intervalId)
console.log('0天00时00分00秒')
} else {
const duration = moment.duration(diff)
const formatted = `${Math.floor(duration.asDays())}天${String(duration.hours()).padStart(2, '0')}时${String(duration.minutes()).padStart(2, '0')}分${String(duration.seconds()).padStart(2, '0')}秒`
console.log(formatted)
}
}, 1000)
}
countdown('2024-12-31T23:59:59')number-precision
数字精度处理函数
安装:npm install number-precision --save
js
NP.strip(num) // 计算精度数,第二个参数可保留位数(无四舍五入)
NP.plus(num1, num2, num3, ...) // 加
NP.minus(num1, num2, num3, ...) // 减
NP.times(num1, num2, num3, ...) // 乘
NP.divide(num1, num2, num3, ...) // 除
NP.round(num, ratio) // 解决 toFixed 四舍五入出错的问题NP.strip(num) // 计算精度数,第二个参数可保留位数(无四舍五入)
NP.plus(num1, num2, num3, ...) // 加
NP.minus(num1, num2, num3, ...) // 减
NP.times(num1, num2, num3, ...) // 乘
NP.divide(num1, num2, num3, ...) // 除
NP.round(num, ratio) // 解决 toFixed 四舍五入出错的问题xlsx
安装:
bash
npm install xlsx
yarn add xlsxnpm install xlsx
yarn add xlsx导出 Excel
js
import * as XLSX from 'xlsx'
const data = [
{ name: 'Alice', age: 25, city: 'New York' },
{ name: 'Bob', age: 30, city: 'Los Angeles' },
{ name: 'Charlie', age: 35, city: 'Chicago' },
]
const worksheet = XLSX.utils.json_to_sheet(data)
const workbook = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
XLSX.writeFile(workbook, 'example.xlsx')import * as XLSX from 'xlsx'
const data = [
{ name: 'Alice', age: 25, city: 'New York' },
{ name: 'Bob', age: 30, city: 'Los Angeles' },
{ name: 'Charlie', age: 35, city: 'Chicago' },
]
const worksheet = XLSX.utils.json_to_sheet(data)
const workbook = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
XLSX.writeFile(workbook, 'example.xlsx')导入 Excel
html
<input type="file" id="upload" /><input type="file" id="upload" />js
document.getElementById('upload').addEventListener('change', (event) => {
const file = event.target.files[0]
const reader = new FileReader()
reader.onload = (e) => {
const data = new Uint8Array(e.target.result)
const workbook = XLSX.read(data, { type: 'array' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const jsonData = XLSX.utils.sheet_to_json(worksheet)
console.log(jsonData)
}
reader.readAsArrayBuffer(file)
})document.getElementById('upload').addEventListener('change', (event) => {
const file = event.target.files[0]
const reader = new FileReader()
reader.onload = (e) => {
const data = new Uint8Array(e.target.result)
const workbook = XLSX.read(data, { type: 'array' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const jsonData = XLSX.utils.sheet_to_json(worksheet)
console.log(jsonData)
}
reader.readAsArrayBuffer(file)
})设置单元格样式
js
worksheet['A1'] = { v: 'Header', s: { font: { bold: true, color: { rgb: 'FF0000' } } } }worksheet['A1'] = { v: 'Header', s: { font: { bold: true, color: { rgb: 'FF0000' } } } }设置列宽和行高
js
worksheet['!cols'] = [{ wpx: 100 }, { wpx: 200 }, { wpx: 300 }]
worksheet['!rows'] = [{ hpx: 20 }, { hpx: 30 }, { hpx: 40 }]worksheet['!cols'] = [{ wpx: 100 }, { wpx: 200 }, { wpx: 300 }]
worksheet['!rows'] = [{ hpx: 20 }, { hpx: 30 }, { hpx: 40 }]多工作表
js
const workbook = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(workbook, sheet1, 'Sheet1')
XLSX.utils.book_append_sheet(workbook, sheet2, 'Sheet2')
XLSX.writeFile(workbook, 'multiple_sheets.xlsx')const workbook = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(workbook, sheet1, 'Sheet1')
XLSX.utils.book_append_sheet(workbook, sheet2, 'Sheet2')
XLSX.writeFile(workbook, 'multiple_sheets.xlsx')SortableJS
功能强大的 JavaScript 拖拽库
ElementUI Table 使用
js
import Sortable from "sortablejs"
const el = document.querySelector(".el-table__body-wrapper tbody")
new Sortable(el, {
animation: 150,
handle: ".table-move",
ghostClass: "blue-background-class",
})import Sortable from "sortablejs"
const el = document.querySelector(".el-table__body-wrapper tbody")
new Sortable(el, {
animation: 150,
handle: ".table-move",
ghostClass: "blue-background-class",
})配置项:https://sortablejs.com/options
vue-cropper(图片修剪)
安装:
bash
npm install vue-cropper
yarn add vue-croppernpm install vue-cropper
yarn add vue-croppervue
<vue-cropper
ref="cropper"
:img="options.img"
:autoCrop="options.autoCrop"
:fixedBox="options.fixedBox"
:canMoveBox="options.canMoveBox"
:autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight"
:centerBox="options.centerBox"
:fixed="options.fixed"
:fixedNumber="options.fixedNumber"
:canMove="options.canMove"
:canScale="options.canScale"
@realTime=realTime />
<div :style="previewStyle">
<div :style="previews.div"><img :src="previews.url" :style="previews.img"></div>
</div><vue-cropper
ref="cropper"
:img="options.img"
:autoCrop="options.autoCrop"
:fixedBox="options.fixedBox"
:canMoveBox="options.canMoveBox"
:autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight"
:centerBox="options.centerBox"
:fixed="options.fixed"
:fixedNumber="options.fixedNumber"
:canMove="options.canMove"
:canScale="options.canScale"
@realTime=realTime />
<div :style="previewStyle">
<div :style="previews.div"><img :src="previews.url" :style="previews.img"></div>
</div>js
const options = ref({
autoCrop: true,
fixedBox: false,
canMoveBox: true,
autoCropWidth: 200,
autoCropHeight: 200,
fixed: true,
fixedNumber: [1, 1],
centerBox: true,
canMove: false,
canScale: false
})
function realTime(data) {
previewStyle.value = {
width: data.w + "px",
height: data.h + "px",
overflow: "hidden",
margin: "0",
zoom: 0.5,
borderRadius: "50%"
}
previews.value = data
}const options = ref({
autoCrop: true,
fixedBox: false,
canMoveBox: true,
autoCropWidth: 200,
autoCropHeight: 200,
fixed: true,
fixedNumber: [1, 1],
centerBox: true,
canMove: false,
canScale: false
})
function realTime(data) {
previewStyle.value = {
width: data.w + "px",
height: data.h + "px",
overflow: "hidden",
margin: "0",
zoom: 0.5,
borderRadius: "50%"
}
previews.value = data
}styled-components
通过 JavaScript 改变 CSS 编写方式,all in js 思想。
基本
js
const StyleApp = styled.div`
background: yellow;
border: 1px solid black;
ul li { color: red; }
&:hover { background: pink; }
`const StyleApp = styled.div`
background: yellow;
border: 1px solid black;
ul li { color: red; }
&:hover { background: pink; }
`透传 props
js
const StyledInput = styled.input`
color: red;
background: yellow;
`
<StyledInput type="text" placeholder="okok" />const StyledInput = styled.input`
color: red;
background: yellow;
`
<StyledInput type="text" placeholder="okok" />基于 props 判断
js
const StyledButton = styled.button`
background: ${(props) => props.bg || 'blue'};
`const StyledButton = styled.button`
background: ${(props) => props.bg || 'blue'};
`样式化任意组件
js
const Child = (props) => <div className={props.className}>child</div>
const StyledChild = styled(Child)` background: red; `const Child = (props) => <div className={props.className}>child</div>
const StyledChild = styled(Child)` background: red; `扩展样式
js
const MyButton = styled.button` background: yellow; `
const BigButton = styled(MyButton)` height: 100px; width: 100px; `const MyButton = styled.button` background: yellow; `
const BigButton = styled(MyButton)` height: 100px; width: 100px; `动画
js
import styled, { keyframes } from 'styled-components'
const rotate360 = keyframes`
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
`
const Rotate = styled.div`
width: 100px; height: 100px;
background: yellow;
animation: ${rotate360} 1s linear infinite;
`import styled, { keyframes } from 'styled-components'
const rotate360 = keyframes`
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
`
const Rotate = styled.div`
width: 100px; height: 100px;
background: yellow;
animation: ${rotate360} 1s linear infinite;
`Element UI
表格排序
vue
<el-table :default-sort="{ prop: 'creation_time', order: 'descending' }">
<el-table-column prop="creation_time" sortable />
</el-table><el-table :default-sort="{ prop: 'creation_time', order: 'descending' }">
<el-table-column prop="creation_time" sortable />
</el-table>表格手风琴效果
js
expandChange(row, expandedRows) {
if (expandedRows.length > 1) {
this.expands = []
if (row) this.expands.push(row)
this.$refs.table.toggleRowExpansion(expandedRows[0])
} else {
this.expands = []
}
}expandChange(row, expandedRows) {
if (expandedRows.length > 1) {
this.expands = []
if (row) this.expands.push(row)
this.$refs.table.toggleRowExpansion(expandedRows[0])
} else {
this.expands = []
}
}修改表格头部样式
css
::v-deep .NexineTable thead {
color: #fff;
background-color: rgb(252, 252, 252) !important;
& th, & tr { background-color: transparent; }
}::v-deep .NexineTable thead {
color: #fff;
background-color: rgb(252, 252, 252) !important;
& th, & tr { background-color: transparent; }
}超出省略
vue
<el-table-column prop="address" :show-overflow-tooltip='true' /><el-table-column prop="address" :show-overflow-tooltip='true' />vue-animate-number(VUE 数字动画)
安装:npm install vue-animate-number
js
import Vue from 'vue'
import VueAnimateNumber from 'vue-animate-number'
Vue.use(VueAnimateNumber)import Vue from 'vue'
import VueAnimateNumber from 'vue-animate-number'
Vue.use(VueAnimateNumber)vue
<animate-number from="1" to="10" duration="1000" easing="easeOutQuad" :formatter="formatter"></animate-number>
<animate-number ref="myNum" from="0" to="10" mode="manual"></animate-number>
<button @click="startAnimate()">animate!</button><animate-number from="1" to="10" duration="1000" easing="easeOutQuad" :formatter="formatter"></animate-number>
<animate-number ref="myNum" from="0" to="10" mode="manual"></animate-number>
<button @click="startAnimate()">animate!</button>js
methods: {
formatter(num) { return num.toFixed(2) },
startAnimate() { this.$refs.myNum.start() }
}methods: {
formatter(num) { return num.toFixed(2) },
startAnimate() { this.$refs.myNum.start() }
}animate.css
引入
html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css" /><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css" />使用
html
<div class="animated bounce"></div><div class="animated bounce"></div>类名:infinite(无限循环)、delay-2s/3s/4s/5s、slow(2s)、slower(3s)、fast(800ms)、faster(500ms)
Vue 中使用
vue
<transition enter-active-class="animate__animated animate__bounceInLeft"
leave-active-class="animate__animated animate__hinge">
<div class="box" v-if="isshow"></div>
</transition><transition enter-active-class="animate__animated animate__bounceInLeft"
leave-active-class="animate__animated animate__hinge">
<div class="box" v-if="isshow"></div>
</transition>回调函数
js
element.addEventListener('animationend', function () {
alert('动画完成')
})element.addEventListener('animationend', function () {
alert('动画完成')
})Hiprint(打印插件)
安装:npm install vue-plugin-hiprint
html
<link rel="stylesheet" type="text/css" media="print" href="https://cdn.jsdelivr.net/npm/vue-plugin-hiprint@latest/dist/print-lock.css"><link rel="stylesheet" type="text/css" media="print" href="https://cdn.jsdelivr.net/npm/vue-plugin-hiprint@latest/dist/print-lock.css">js
import * as hiPrint from 'vue-plugin-hiprint'
let hiprintTemplate = new hiPrint.hiprint.PrintTemplate({
template: order_particulars_my_panel,
settingContainer: "#templateDesignDiv",
})
hiprintTemplate.print(printData, {}, {
styleHandler: () => {
let css = '<link href="http://hiprint.io/Content/hiprint/css/print-lock.css" media="print" rel="stylesheet">'
return css
}
})import * as hiPrint from 'vue-plugin-hiprint'
let hiprintTemplate = new hiPrint.hiprint.PrintTemplate({
template: order_particulars_my_panel,
settingContainer: "#templateDesignDiv",
})
hiprintTemplate.print(printData, {}, {
styleHandler: () => {
let css = '<link href="http://hiprint.io/Content/hiprint/css/print-lock.css" media="print" rel="stylesheet">'
return css
}
})
Cao Note