🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 全局工具 * 新建目录`/src/utils` ### 新建文件`/src/utils/util.js` ```javascript export function timeFix() { const time = new Date() const hour = time.getHours() return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好' } export function welcome() { const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 王者荣耀', '我猜你可能累了'] const index = Math.floor(Math.random() * arr.length) return arr[index] } /** * 触发 window.resize */ export function triggerWindowResizeEvent() { const event = document.createEvent('HTMLEvents') event.initEvent('resize', true, true) event.eventType = 'message' window.dispatchEvent(event) } export function handleScrollHeader(callback) { let timer = 0 let beforeScrollTop = window.pageYOffset callback = callback || function () { } window.addEventListener( 'scroll', event => { clearTimeout(timer) timer = setTimeout(() => { let direction = 'up' const afterScrollTop = window.pageYOffset const delta = afterScrollTop - beforeScrollTop if (delta === 0) { return false } direction = delta > 0 ? 'down' : 'up' callback(direction) beforeScrollTop = afterScrollTop }, 50) }, false ) } export function isIE() { const bw = window.navigator.userAgent const compare = (s) => bw.indexOf(s) >= 0 const ie11 = (() => 'ActiveXObject' in window)() return compare('MSIE') || ie11 } /** * Remove loading animate * @param id parent element id or class * @param timeout */ export function removeLoadingAnimate(id = '', timeout = 1500) { if (id === '') { return } setTimeout(() => { document.body.removeChild(document.getElementById(id)) }, timeout) } // 节流 // 思路: 第一次先设定一个变量true, // 第二次执行这个函数时,会判断变量是否true, // 是则返回。当第一次的定时器执行完函数最后会设定变量为flase。 // 那么下次判断变量时则为flase,函数会依次运行。 export function throttle(fn, delay = 100) { // 首先设定一个变量,在没有执行我们的定时器时为null var timer = null return function () { // 当我们发现这个定时器存在时,则表示定时器已经在运行中,需要返回 if (timer) return timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, delay) } } // 防抖 // 首次运行时把定时器赋值给一个变量, 第二次执行时, // 如果间隔没超过定时器设定的时间则会清除掉定时器, // 重新设定定时器, 依次反复, 当我们停止下来时, // 没有执行清除定时器, 超过一定时间后触发回调函数。 export function debounce(fun, delay) { return function (args) { // 获取函数的作用域和变量 const that = this const _args = args // 每次事件被触发,都会清除当前的timeer,然后重写设置超时调用 clearTimeout(fun.id) fun.id = setTimeout(function () { fun.call(that, _args) }, delay) } } /** * 判断是否为空对象 * @param {*} object 源对象 */ export function isEmptyObject(object) { return Object.keys(object).length === 0 } /** * 判断是否为对象 * @param {*} object */ export function isObject(object) { return Object.prototype.toString.call(object) === '[object Object]' } /** * 判断是否为对象 * @param {*} array */ export function isArray(array) { return Object.prototype.toString.call(array) === '[object Array]' } /** * 判断是否为空 * @param {*} object 源对象 */ export function isEmpty(value) { if (isArray(value)) { return value.length === 0 } if (isObject(value)) { return isEmptyObject(value) } return !value } /** * 判断是否在数组中 * @param {*} search * @param {*} array */ export function inArray(search, array) { return array.includes(search) } /** * 获取指定天数的日期 * @param day * @returns {string} */ export function getDateByDay(day) { var today = new Date() var targetdaySeconds = today.getTime() + 1000 * 60 * 60 * 24 * day today.setTime(targetdaySeconds) // 注意,这行是关键代码 return today.getFullYear() + '-' + zeroFillLeft(today.getMonth() + 1) + '-' + zeroFillLeft(today.getDate()) } /** * 左侧补0 * @param value * @returns {*} */ export function zeroFillLeft(value) { return (value.toString().length === 1) ? ('0' + value) : value } /** * 批量给指定对象赋值 * @param obj obj 指定的对象,一般为vue实例 * @param obj assignment 赋值的元素 { a: '123' } */ export function assignment(obj, assignment) { Object.keys(assignment).forEach(key => { obj[key] = assignment[key] }) } ``` ## 全局样式 ### 新建文件`/src/utils/util.less` ```less .textOverflow() { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; word-break: break-all; } .textOverflowMulti(@line: 2, @bg: #fff) { position: relative; max-height: @line * 1.5em; margin-right: -1em; padding-right: 1em; overflow: hidden; line-height: 1.5em; text-align: justify; &::before { position: absolute; right: 14px; bottom: 0; padding: 0 1px; background: @bg; content: '...'; } &::after { position: absolute; right: 14px; width: 1em; height: 1em; margin-top: 0.2em; background: white; content: ''; } } // 文字超出隐藏(一行) // 需要设置文字容器的宽度 .oneline-hide { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; word-break: break-all; } // 文字超出隐藏(两行) // 需要设置文字容器的宽度 .twoline-hide { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; } // 动画 @keyframes fadenum { /*设置内容由显示变为隐藏*/ 0% { opacity: 0; } 100% { opacity: 1; } } /* 浮动 */ .clearfix() { zoom: 1; &::before, &::after { display: table; content: ' '; } &::after { clear: both; height: 0; font-size: 0; visibility: hidden; } } .fl-l { float: left; } .fl-r { float: right; } /* flex布局 */ .flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; } .flex-box { flex: 1; } .flex-dir-row { flex-direction: row; } .flex-dir-column { -webkit-box-orient: vertical; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } .flex-x-center { -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } .flex-x-between { -webkit-box-pack: justify; -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; } .flex-x-around { justify-content: space-around; } .flex-x-end { -webkit-box-pack: end; -ms-flex-pack: end; -webkit-justify-content: flex-end; justify-content: flex-end; } .flex-y-center { -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; } /* 全局函数 */ .hiden { display: none; } // 手型指针 .cur-p { cursor: pointer; user-select: none; } // 外边距 .mt-5 { margin-top: 5px; } .mt-10 { margin-top: 10px; } .mt-15 { margin-top: 20px; } .mt-20 { margin-top: 20px !important; } .mt-30 { margin-top: 30px; } .mt-40 { margin-top: 40px; } .mt-50 { margin-top: 50px; } .mb-0 { margin-bottom: 0 !important; } .mb-5 { margin-bottom: 5px !important; } .mb-10 { margin-bottom: 10px; } .mb-15 { margin-bottom: 15px; } .ml-5 { margin-left: 5px; } .ml-10 { margin-left: 10px; } .mr-5 { margin-right: 5px; } .mr-10 { margin-right: 10px; } .mr-20 { margin-right: 20px; } .mlr-2 { margin-left: 2px; margin-right: 2px; } .mtb-2 { margin-top: 2px; margin-bottom: 2px; } // 文字颜色 .c-p { color: #1890ff !important; } .c-muted-1 { color: #7b7b7b; } // 字体大小 .f-12 { font-size: 12px; } .f-13 { font-size: 13px; } .f-w-b { font-weight: bold; } // 删除线 .f-through { text-decoration: line-through; } ``` ### 新建文件`/src/global.less` ```less @import './utils/utils.less'; // 滚动条样式 ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-thumb { border-radius: 10px; background-color: #bdbdbd; -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); } html, body, #app, #root { height: 100%; } iframe { border: 0; } p { // margin: 0 !important margin: 0 } .colorWeak { filter: invert(80%); } .ant-layout.layout-basic { height: 100vh; min-height: 100vh; } canvas { display: block; } body { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } ul, ol { list-style: none; } // 数据列表 样式 .table-alert { margin-bottom: 16px; } // 数据列表 操作 .table-operator { margin-bottom: 18px; .search-btn { margin-right: 8px; } } // 数据列表 搜索条件 .table-page-search-wrapper { .ant-form-inline { .ant-form-item { display: flex; margin-bottom: 24px; margin-right: 0; .ant-form-item-control-wrapper { flex: 1 1; display: inline-block; vertical-align: middle; } > .ant-form-item-label { line-height: 32px; padding-right: 8px; width: auto; } .ant-form-item-control { height: 32px; line-height: 32px; } } } .table-page-search-submitButtons { display: block; margin-bottom: 24px; white-space: nowrap; } } // 内容页card组件标题 .card-title { font-size: 16px; margin-bottom: 16px; color: rgba(0, 0, 0, 0.75); } // 图标按钮样式 .ant-btn > .anticon + span, .ant-btn > span + .anticon { margin-left: 5px; } // 表单 .ant-form { .ant-form-explain, .ant-form-extra { font-size: 13px; } .form-item-help { font-size: 12px; // line-height: 2; line-height: 1.5; padding-top: 4px; min-height: 22px; margin-top: -2px; transition: color 0.3s cubic-bezier(0.215, 0.61, 0.355, 1); a { margin: 0 3px; } p.extra, small { color: rgba(0, 0, 0, 0.45); font-size: 13px !important; } p.extra { margin-bottom: 5px; } } } // 级联选择器 .ant-cascader-menu { height: 225px; } // 分割线 .ant-divider { margin: 30px 0 !important; .ant-divider-inner-text { font-size: 13px; color: rgba(0, 0, 0, 0.61); } } .ant-divider-horizontal.ant-divider-with-text-left::before { width: 5%; } //# 兼容外部样式 // ueditor .edui-default { .edui-editor { // z-index: 2 !important; font-size: 14px; line-height: normal; border-radius: 0; -webkit-border-radius: 0; -moz-border-radius: 0; pre { overflow: unset; } } .edui-editor-toolbarboxouter { box-shadow: unset; background-image: linear-gradient(to bottom, #ffffff, #fbfbfb); } .edui-editor-toolbarbox { box-shadow: unset; } // 自定义图片按钮 .edui-for-image-button .edui-icon { background-position: -380px 0px; } } // ## 自定义模块 ## .ant-table { // 操作栏 项目间距 .actions > a { margin-right: 8px; &:last-child { margin-right: 0; } } } // 搜索表单 .search-form { margin-bottom: 5px; .ant-form-item { margin-bottom: 10px; } .ant-form-item-control-wrapper { min-width: 220px; } .search-btn { .ant-form-item-control-wrapper { width: auto; min-width: auto; } } } // 列表页-操作按钮组 .row-item-tab { & > button { margin-right: 5px; } } // 无边框的modal .ant-modal-root { &.noborder { .ant-modal-header { border-bottom: none; } .ant-modal-footer { border-top: none; } .ant-modal-body { padding: 5px 24px 15px 24px; } } } // 表格不允许换行 .ant-table { td, th { white-space: nowrap; } } // Alert 警告提示 (banner) .ant-alert-banner { margin-bottom: 15px; padding-left: 40px; .ant-alert-message { font-size: 13px; } // 黄色警告 &.ant-alert-warning { background-color: #fffcee; border: 1px solid #fff0c1; } // 标题+描述 &.ant-alert-with-description { padding-left: 55px; .ant-alert-icon { font-size: 18px; top: 16px; left: 25px; } .ant-alert-message { font-size: 14px; margin-bottom: 6px; // margin-bottom: 0; } .ant-alert-description { font-size: 12.3px; } } } ``` ## 在`/src/main.js`中引入全局样式 ```javascript import './global.less` ```