基于Vue源码设计思想,封装的一套日常开发工具类
在我们日常开发中,每个公司都有自己的工具类,当然封装的方法不同, 有的可能就会放在一个 utils/index.js
文件中, 但是这样存在一个问题就是,如果方法过多的话,维护起来很麻烦,后面就想了一下,对模块进行拆分,常见的比如分为: base、date、file、data、security...
等模块,每个模块做自己对应的方法,如有新增模块,只需要在 utils/index
暴露出去即可, 最后对外界通过index.js
导入使用, 这样实现的功能是一样的,而且维护成本低了很多。
1.目录结构
|-- Utils基本结构
|-- index.js #对外界暴露使用
|-- install_prototype.js #挂载到Vue原型
|-- README.MD #描述文档
|-- models #工具模块
|-- base.js #基本
|-- data.js #数据
|-- date.js #日期
|-- file.js #文件
|-- security.js #安全
|...
2.安装使用
- 由于各个模块中可能有其他依赖,所以建议先
npm i crypto-js
安装依赖; - 在
main.js
中import instalUtils from '@/utils/install_prototype'
; - 然后再
Vue.use(instalUtils)
; - 组件中
import { getType } from '@/utils/index';
或this.$utils.getType()
;
3.Data模块
/**
* 存储数据
* @param {String, Object} key 字段名
* @param value 字段值
* @return void
*/
export const setStore = (key = "", value) => {
if (!key) return;
if (!key instanceof Object) return localStorage.setItem(key, value);
Object.keys(key).forEach(dataKey => {
let dataValue = typeof key[dataKey] === 'object' ? JSON.stringify(key[dataKey]) : key[dataKey];
localStorage.setItem(dataKey, dataValue);
});
}
/**
* 获取数据
* @param {String, Array} key 键名
* @return {String, Object}
*/
export const getStore = (key = "") => {
if (typeof key === 'string') return localStorage.getItem(key);
let dataRes = {};
key.forEach(dataKey => {
dataRes[dataKey] = localStorage.getItem(dataKey) || null;
});
return dataRes;
}
/**
* 删除数据
* @param {String, Array} key 键名
* @return void
*/
export const deleteStore = (key = "") => {
let removeKeys = [...key];
removeKeys.forEach(dataKey => {
localStorage.removeItem(dataKey);
});
}
/**
* 清空Store
* @return void
*/
export const clearStore = () => {
localStorage.clear();
}
/**
* 通过key找到在列表中对应的显示
* @param {Object} obj
* @param obj.dataList 数据列表
* @param obj.value 数据的值对应的字段名称 例如 'value'
* @param obj.label 数据的说明对应的字段名称 例如 'label'
* @param obj.data 当前传入的数据值
* @return name 返回当前传入值在数组中对应的名字
*/
export const getDataName = obj => {
let name = obj.data;
if (Array.isArray(obj.dataList) && obj.dataList.length > 0) {
for (let i = 0; i < obj.dataList.length; i++) {
if (obj.dataList[i][obj.value] === obj.data) {
name = obj.dataList[i][obj.label];
}
}
}
return name;
}
/**
* json对象转FormData
* @param obj
* @returns {*}
*/
export const jsonToFormData = (obj, oldFormData) => {
let formData = oldFormData || new FormData();
if (obj) {
for (let k in obj) {
formData.append(k, obj[k]);
}
}
return formData;
}
/**
* 移除对象中的空字符串
* @param test
* @param recurse
*/
export const deleteEmptyString = (test, recurse) => {
for (let i in test) {
if (test[i] === '') {
delete test[i];
} else if (recurse && typeof test[i] === 'object') {
deleteEmptyString(test[i], recurse);
}
}
}
/**
* 删除对象中的空Key
* @param test
* @param recurse
*/
export const deleteEmptyObject = (test, recurse) => {
for (let i in test) {
if (test[i] === undefined || test[i] === null || test[i] === '') {
delete test[i];
} else if (recurse && typeof test[i] === 'object') {
deleteEmptyObject(test[i], recurse);
}
}
}
/**
* 移除对象中的无效属性
* @param obj
* @return {*}
*/
export const removeEmpty = obj => {
Object.keys(obj).forEach(function (key) {
(obj[key] &&
typeof obj[key] === 'object' &&
removeEmpty(obj[key])) ||
((obj[key] === undefined || obj[key] === null || obj[key] === '') &&
delete obj[key]);
});
return obj;
}
/**
* 深度拷贝
* @param {*} obj
*/
export const deepCloneObject = obj => {
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === 'object') {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
//判断ojb子元素是否为对象,如果是,递归复制
if (obj[key] && typeof obj[key] === 'object') {
objClone[key] = deepCloneObject(obj[key]);
} else {
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
/**
* 获取页面参数
* @param key 参数名称,不传则返回全部参数
*/
export const getQueryParam = key => {
let paramValue = '';
let hash = window.location.hash;
let paramStr = hash ? (hash.indexOf('?') ? hash.split('?')[1] : '') : '';
let paramObj = {}; //参数对象
if (paramStr) {
paramStr.split('&').forEach(param => {
let arr = param.split('=');
let paramKey = arr[0];
let value = decodeURIComponent(arr[1]);
paramObj[paramKey] = value;
if (key && key === paramKey) {
paramValue = value;
}
});
}
if (key) return paramValue;
return paramObj;
}
/**
* json参数转为query
* @param Object paramObj
* @return String user=1&sex=0
*/
export const paramToQS = paramObj => {
if (!(paramObj instanceof Object)) return '';
return Object.keys(paramObj)
.map(parkey => `${parkey}=${encodeURIComponent(paramObj[parkey])}`)
.join('&');
}
/**
* 线性数据转化为树
* @param {Object} data 源数据
* @param {Object} parentKey 父级id key
* @param {childrenKey} childrenKey 子集key
* @param {Object} pId 父级标识符
*/
export const toTree = (data, parentKey, childrenKey, pId) => {
let tree = [];
let temp = null;
for (let i = 0; i < data.length; i++) {
if (data[i][parentKey] === pId) {
let obj = data[i];
temp = toTree(data, parentKey, childrenKey, data[i][childrenKey]);
if (temp.length > 0) {
obj.children = temp;
}
tree.push(obj);
}
}
return tree;
}
/**
* 转换Key
* @param obj
* @param keyMap
* @param isDeep Boolean 是否深度
* @return Object/Array
*/
export const convertKey = (obj, keyMap, isDeep) => {
if (!['[object Array]', '[object Object]'].includes(Object.prototype.toString.call(obj))) {
throw new TypeError('The first argument should be either an object or an array!');
}
if (Object.prototype.toString.call(keyMap) !== '[object Object]') {
throw new TypeError('The parameter keyMap should be an object!');
}
let res = obj instanceof Array ? [] : {};
if (obj instanceof Object) {
for (let key in obj) {
let newKey = Object.keys(keyMap).includes(key) ? keyMap[key] : key;
res[newKey] = obj[key];
//是否为深度转换
if (isDeep && obj[key] instanceof Object && Object.keys(obj[key]).length) {
res[newKey] = convertKey(obj[key], keyMap, isDeep);
}
}
}
return res;
}
/**
* 设置tree层级信息
* @param {Object} data
* @param {Object} maxLevel 最多层级
* @param {Object} currLevel 当前层级,可不传
*/
export const setTreeHierarchyIndex = function (data, maxLevel=10, currLevel) {
if (!(data instanceof Array)) throw new TypeError('The data should be an array!');
let result = [];
for (let k = 0; k < data.length; k++) {
// console.log('当前层级:', currLevel);
// console.log('是否在指定层级范围:', currLevel < maxLevel);
let temp = data[k];
let newNode = {
...temp,
hierarchyIndex: currLevel + 1,
children: null
};
delete newNode.children;
//是否在指定层级范围
if (currLevel >= maxLevel) continue;
if (temp.children && temp.children.length > 0) {
currLevel++
newNode.children = setTreeHierarchyIndex(temp.children, maxLevel, currLevel);
currLevel--
}
result.push(newNode);
}
return result;
}
/**
* 复制数据
* @param {*} data
* @param {Number} count
* @return {*}
*/
export const copyData = (data, count = 5) => new Array(count).fill(data);
/**
* 格式化金钱,每千分位加逗号
* @param {String} str
*/
export const formatMoney = (str = "") => {
if (!str) return "";
str = str.toString();
let s = '';
let count = 0;
for (let i = str.length - 1; i >= 0; i--) {
count++
s = str[i] + s
if (count % 3 == 0 && i != 0) s = ',' + s;
}
return s
}
/**
* 扁平化数组
* @param {Array} arr
* @returns {Array}
*/
export const flatArr = (arr=[]) => {
return arr.reduce((item, next) => item.concat(Array.isArray(next) ? flatArr(next) : next, []), []);
}
/**
* 是否为json
* @param {*} data
* @returns {Boolean}
*/
export const isJson = (data=null) => {
try {
if (typeof data !== 'string') return false;
let jsonObj = JSON.parse(data);
return !!(jsonObj && typeof jsonObj === 'object');
} catch (error) {
console.log(error);
return false;
}
}
/**
* 删除array/obj中的Key
* @param {Array|Object} data
* @param {Array} keys
* @returns {Array|Object}
*/
const deleteMapKey = (data = null, keys = null) => {
keys = keys instanceof Array ? keys : keys ? [keys] : keys;
const dataType = Object.prototype.toString.call(data).slice(8, -1).toLowerCase();
if (!['array', 'object'].includes(dataType) || !(keys instanceof Array)) return data;
//生成新的Map
let genNewMap = (obj, diskeys) => {
Object.keys(obj).forEach(key => {
keys.includes(key) && delete obj[key];
});
return obj;
}
//array or obj
if (dataType === 'array') {
return data.map(item => (typeof item === 'object' ? genNewMap(item, keys) : item));
} else {
return genNewMap(data, keys);
}
}
4.注意事项
-
本工具类 Vue 项目可以拿来直接使用,如果是React或其他项目,需要挂载到原型的话需要更改
install_prototype.js
这个文件; -
为了风格统一,请使用
import {fn1, fn2, fn3, ...fnx} from '@/utils'
方式使用;
更多方法持续更新中...