1.利用Cookie,来设置接口携带的‘token’
执行命令npm install js-cookie,在js工具类中引入,
import Cookie from 'js-cookie'; function getToken() { return Cookie.get('token'); } function setToken(token) { Cookie.set('token', token); } function removeToken() { Cookie.remove('token'); } export default { getToken, setToken, removeToken };
2.利用日期moment.js工具,来完成对周次以及星期的处理 ,包含了 获取一年的每周的周次,以及每周的开始日期,结束日期,以及当前属于星期几等方法
执行npm install moment.js
3.vue自定义指令工具类,vue的全局自定义指令,
例如:当从一个获取到焦点的input框 点击另一个input框时,这个被点击的input框不会自动获取到焦点,这个时候就可以利用Vue.directive()自定义指令
4.vue支持render渲染函数,
例如:vue+elemetn-ui 里面的table跟render进行搭配简化代码
执行npm install moment.js
import moment from 'moment'; //获取前一周的开始时间,结束时间,以及周数 function getPreWeek(week) { if (isParamBlank(week)) { return; } var startDate = moment() .week(week - 1) .startOf('week') .add(1, 'days') .format('YYYY-MM-DD'); //这样是年月日的格式 var endDate = moment() .week(week - 1) .endOf('week') .add(1, 'days') .format('YYYY-MM-DD'); var weekCount = moment(moment(startDate).subtract(1, 'days')).weeks(); var preWeekInfo = { startDate: startDate, endDate: endDate, weekCount: weekCount }; return preWeekInfo; } // 获取下一周的起始日期和结束日期,以及周数 function getNextWeek(week) { if (isParamBlank(week)) { return; } var startDate = moment() .week(week + 1) .startOf('week') .add(1, 'days') .format('YYYY-MM-DD'); //这样是年月日的格式 var endDate = moment() .week(week + 1) .endOf('week') .add(1, 'days') .format('YYYY-MM-DD'); var weekCount = moment(moment(startDate).subtract(1, 'days')).weeks(); var nextWeekInfo = { startDate: startDate, endDate: endDate, weekCount: weekCount }; return nextWeekInfo; } // 根据传入参数,获取周次信息 function getWeekInfoByDate(param) { if (isParamBlank(param)) { // 当前时间所在周数 return; } var date = moment(param); var startDate = moment() .week(moment(date).week()) .startOf('week') .add(1, 'days') .format('YYYY-MM-DD'); //这样是年月日的格式 var endDate = moment() .week(moment(date).week()) .endOf('week') .add(1, 'days') .format('YYYY-MM-DD'); var weekCount = moment(moment(startDate).subtract(1, 'days')).weeks(); // 获取当前的周次 , 如果不穿参数,则表示当前的周数 ,如果传入时间,则表示 该时间段所在的周数 //因为是基于moment.js 起始时间还是从周日开始算的 ,所以需要在现有的基础上减去一天 ,这样也是为了防止边界情况出错 var weekInfo = { startDate: startDate, endDate: endDate, weekCount: weekCount }; return weekInfo; } // 获取一年中的总周次 function getWeekTotalInYear() { return moment().weeksInYear(); } //校验参数是否为空 function isParamBlank(param) { if (typeof param == 'undefined' || param == null || param.length == 0) { return true; } return false; } // 获取当前周的周数以及该周的开始时间和结束时间 function getCurrentWeekInfo() { // var weekCount = moment( moment(moment().week(moment().week()).startOf('week')).subtract(1,'days')).weeks(); var weekCount = moment(moment().subtract(1, 'days')).weeks(); var startDate = moment() .week(weekCount) .startOf('week') .add(1, 'days') .format('YYYY-MM-DD'); //这样是年月日的格式 var endDate = moment() .week(weekCount) .endOf('week') .add(1, 'days') .format('YYYY-MM-DD'); var currentWeekInfo = { startDate: startDate, endDate: endDate, weekCount: weekCount }; return currentWeekInfo; } function getDayByWeekDay(week, weekNum) { if (isParamBlank(week) && isParamBlank(weekNum)) { return; } return moment() .week(week) .startOf('week') .add(weekNum, 'days') .format('YYYY-MM-DD'); //这样是年月日的格式 } //start of 2019-2-18 新增 //为了解决点击上一周和下一周的 边界值情况,新增以下两个函数 //点击上一周 function clickPreIconGetPreWeek(week, currentWeekStartTime) { if (isParamBlank(week) && isParamBlank(currentWeekStartTime)) { return; } var startDate = moment(currentWeekStartTime) .subtract(7, 'days') .format('YYYY-MM-DD'); var endDate = moment(startDate) .add(6, 'days') .format('YYYY-MM-DD'); var weekCount = moment(moment(startDate).subtract(1, 'days')).weeks(); var preWeekInfo = { startDate: startDate, endDate: endDate, weekCount: weekCount }; return preWeekInfo; } //点击下一周 function clickNextIconGetNextWeek( week, currentWeekStartTime, currentWeekEndTime ) { if (isParamBlank(week) && isParamBlank(currentWeekEndTime)) { return; } var startDate = moment(currentWeekStartTime) .add(7, 'days') .format('YYYY-MM-DD'); var endDate = moment(startDate) .add(6, 'days') .format('YYYY-MM-DD'); var weekCount = moment(moment(startDate).subtract(1, 'days')).weeks(); var nextWeekInfo = { startDate: startDate, endDate: endDate, weekCount: weekCount }; return nextWeekInfo; } //end of 2019-2-18 新增 export const dateUtils = { getPreWeek: getPreWeek, clickPreIconGetPreWeek: clickPreIconGetPreWeek, clickNextIconGetNextWeek: clickNextIconGetNextWeek, getNextWeek: getNextWeek, getWeekTotalInYear: getWeekTotalInYear, getCurrentWeekInfo: getCurrentWeekInfo, getWeekInfoByDate: getWeekInfoByDate, getDayByWeekDay: getDayByWeekDay };
3.vue自定义指令工具类,vue的全局自定义指令,
例如:当从一个获取到焦点的input框 点击另一个input框时,这个被点击的input框不会自动获取到焦点,这个时候就可以利用Vue.directive()自定义指令
/** @format */ /*Vue全局指令*/ import Vue from 'vue'; /** * Vue 跳转指令'v-jump',基于router.push方式 * @param name/path 路由名或路径(必传)[eg:home或/home] * @param param 参数[eg:{id:123}] * @param type 按什么方式传递参数[1-按路由配置方式[eg:home/123];2-按param方式[eg:{name/path:'',params:{id:123}}];3-按query方式(默认)[eg:{name/path:'',query:{id:123}}]] * 例子:<div class="click-wrap" :data-id="item.id" v-jump="['home_detail', {id:123}, 2]"> */ Vue.directive('jump', { // el: 指令绑定的元素 // vm: 拥有该指令的上下文 ViewModel // expression: 指令的表达式,不包括参数和过滤器 // arg: 指令的参数 // raw: 未被解析的原始表达式 // name: 不带前缀的指令名 bind: function(el, binding, vnode) { // 做绑定的准备工作(比如添加事件监听器,或是其他只需要执行一次的复杂操作) // 若和v-for指令共用,由于v-for的就地重用机制,需要指定一个唯一的key属性(对应vnode.key),如果没有指定,这里需要修改 vnode.key = Math.round(Math.random() * 12568); el.handler = function() { let data = binding.value || null; if (data) { let vm = vnode.context; let pathName = data[0] || null; let param = data[1] || null; let type = data[2] || 3; // console.log('v-jump数据:', pathName, param, type); if (pathName) { if (type === 1) { /*path类型单独处理参数格式*/ if (param) { var pStr = []; for (let j in param) { if (param.hasOwnProperty(j)) { param[j] ? pStr.push(param[j]) : null; } } } vm.$router.push({ path: '/' + pathName + (param ? '/' + pStr.join('/') : '') }); } if (type === 2) { vm.$router.push({ name: pathName, params: param }); } if (type === 3) { vm.$router.push({ path: '/' + pathName, query: param }); } else { if (pathName.indexOf('/') > -1) { vm.$router.push({ path: pathName }); } else { vm.$router.push({ name: pathName }); } } } else { console.warn('好歹给个页面名啊!'); } } else { console.error('v-jump似乎还需要点什么!'); } }; /*为Dom绑定事件*/ el.addEventListener('click', el.handler, false); }, update: function(newValue, oldValue) { // 根据获得的新值执行对应的更新(对于初始值也会被调用一次) }, unbind: function(el) { // 做清理工作(比如移除在 bind() 中添加的事件监听器) /*为Dom移除事件*/ el.removeEventListener('click', el.handler); } }); /** * Vue 指令'v-open',打开新页面 * @param name/path 路由名或路径(必传)[eg:home或/home] * @param param 参数[eg:{id:123}] * 例子:<div class="click-wrap" :data-id="item.id" v-open="['home_detail', {id:123}]"> */ Vue.directive('open', { bind: function(el, binding, vnode) { vnode.key = new Date().getTime() * 3579; el.handler = function() { let data = binding.value || null; if (data) { let vm = vnode.context; let pathName = data[0] || null; let param = data[1] || null; // console.log('v-open数据:', pathName, param); let routeData = vm.$router.resolve({ name: '新页面打开', path: pathName, query: param }); window.open(routeData.href, '_blank'); } else { console.error('v-open似乎还需要点什么!'); } }; el.addEventListener('click', el.handler, false); }, unbind: function(el) { el.removeEventListener('click', el.handler); } }); /** * Vue input限制只能输入正整数(可控制最小最大值) * 例子:<input type="text" v-integer="{min:1, max:10}"> */ Vue.directive('integer', { bind: function(el, binding) { let attr = binding.value; //传入的参数 /* var position = binding.modifiers; //获取对象数组,使用需要遍历 var warning = binding.arg; //获取true属性 */ // console.log(attr); el.handler = function() { el.value = el.value.replace(/\D+/, ''); attr.max !== undefined ? el.value > attr.max ? (el.value = attr.max) : null : null; attr.min !== undefined ? el.value < attr.min ? (el.value = attr.min) : null : null; }; el.addEventListener('input', el.handler); }, unbind: function(el) { el.removeEventListener('input', el.handler); } }); /** * Vue 页面显示input框时自动获取焦点 * 例子: */ Vue.directive('myfocus', { inserted: function(el, binding) { // console.log(el); // let mtinput = el.querySelector('input'); el.focus(); } }); /* Vue.directive('blur', { bind: function(el, binding, vnode) { let mtinput = el.querySelector('input'); mtinput.onfocus = function() { //如果要对节点的数据进行更改,且更改要映射到页面上,则更改可在vnode.context上进行,这样,改完之后,改变就会映射到页面 }; mtinput.onblur = function() { //同上理 }; }, unbind: function(el) { el.removeEventListener('input', el.handler); } }); */
例如:vue+elemetn-ui 里面的table跟render进行搭配简化代码
/** @format 写进expand.js文件里*/ export default { name: 'TableExpand', functional: true, props: { row: Object, render: Function, index: Number, column: { type: Object, default: null } }, render: (h, ctx) => { const params = { row: ctx.props.row, index: ctx.props.index }; if (ctx.props.column) params.column = ctx.props.column; return ctx.props.render(h, params); } };
在common-table.vue文件中这样写
<!-- @format --> <template> <div class="common-table"> <el-table :data="tableData" @selection-change="handleSelectionChange" @sort-change="handleSortChange" stripe border :show-summary="summary.enable" :sum-text="summary.text" > <template v-for="item in columnsData"> <template v-if="item.type === 'options'"> <el-table-column :key="item.prop" :prop="item.prop" :label="item.label" :width="item.width" :sortable="item.sortable" :type="item.type" :show-overflow-tooltip="item.tooltip" > <template slot-scope="scope"> <expand :render="item.render" :row="scope.row" :column="item"> </expand> </template> </el-table-column> </template> <template v-else> <el-table-column :key="item.prop" :prop="item.prop" :label="item.label" :width="item.width" :sortable="item.sortable" :type="item.type" :show-overflow-tooltip="item.tooltip" :formatter="item.formatter" :selectable="item.selectable" > </el-table-column> </template> </template> </el-table> </div> </template> <script> /* 添加 render函数扩展 */ import Expand from '@/utils/expand'; export default { name: 'ComTable', components: { Expand }, props: { columnsData: { type: Array, default: () => { return []; }, required: true }, tableData: { type: Array, default: () => { return []; }, required: true }, summary: { type: Object, default: () => { return { enable: false, text: '合计' }; } } }, data() { return { multipleSelection: [] }; }, methods: { /** * 点击三角形排序 * @param column */ handleSortChange(column) { this.$emit('sortChange', column); }, /** * 实时获取选择数据数组 * @param val */ handleSelectionChange(val) { this.multipleSelection = val; this.$emit('selectionChange', val); } } }; </script>
5.vue全局过滤函数,
!切记一定要在最外层的main.js或者是index.js里面 引入该filter.js文件
例如:将日期时间戳转化为字符串时间,
{{ item.startTime | timeFormat('yyyy-MM-dd HH:mm') }} -
{{ item.endTime | timeFormat('HH:mm') }}
/** @format */ import Vue from 'vue'; /** * 时间戳转日期格式 * @param data {number} 时间戳 * @param format {string} 时间格式[完整格式:yyyy-MM-dd HH:mm:ss,默认yyyy-MM-dd] * @param implementText {string} 缺省文字 */ const timeFormat = function(data, format, implementText) { if (data === null || data === '' || data === undefined) { return implementText || ''; } format = format || 'yyyy-MM-dd'; let week = [ '星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ]; let date = new Date(data); let o = { 'M+': date.getMonth() + 1, 'd+': date.getDate(), 'h+': date.getHours() % 12, 'H+': date.getHours(), 'm+': date.getMinutes(), 's+': date.getSeconds(), 'q+': Math.floor((date.getMonth() + 3) / 3), 'S+': date.getMilliseconds(), 'W+': week[date.getDay()] }; if (/(y+)/.test(format)) format = format.replace( RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length) ); for (let k in o) if (new RegExp('(' + k + ')').test(format)) format = format.replace( RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length) ); return format; }; Vue.filter('timeFormat', timeFormat); /** * 年级code转年级名称 * @param data 数值 * @param implementText 缺省文案 */ Vue.filter('revealGradeName', function(data, implementText) { if (data) { const gradeList = JSON.parse(sessionStorage.getItem('staticGrades')); return gradeList.filter(cur => cur.id === data)[0].name || ''; } else { return implementText || ''; } }); /** * 学段code转学段名称 * @param data 数值 * @param implementText 缺省文案 */ Vue.filter('revealPhaseName', function(data, implementText) { return data ? { '03': '小学', '04': '初中', '05': '高中' }[data] : implementText || ''; }); /** * 学科code转学科名称 * @param data 数值 * @param implementText 缺省文案 */ Vue.filter('revealSubjectName', function(data, implementText) { if (data) { const subjectList = JSON.parse(sessionStorage.getItem('staticSubjects')); return subjectList.filter(cur => cur.id === data)[0].name || ''; } else { return implementText || ''; } }); /** * 保留小数位 * @param data 数值 * @param len 保留的位数 */ Vue.filter('toFixed', function(data, len) { if (data) { typeof data === 'string' ? (data = Number(data)) : null; return data ? data.toFixed(len || 2) : data; } else { return 0; } }); Vue.prototype.$timeFormat = timeFormat;
6.vue的utils.js工具类常用方法,
!切记一定要在最外层的main.js或者是index.js里面 引入该utils.js文件
例如:浅拷贝 ,深拷贝,数据处理 等方法,
/** * 将秒数转为时间格式 * * @format * @param data {number} 时间戳 * @param format {string} 时间格式[完整格式:yyyy-MM-dd HH:mm:ss,默认yyyy-MM-dd] * @param implementText {string} 缺省文字 */ export function timeFormat(data, format, implementText) { if (data === null || data === '' || data === undefined) { return implementText || ''; } format = format || 'yyyy-MM-dd'; let week = [ '星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ]; let date = new Date(data); let o = { 'M+': date.getMonth() + 1, 'd+': date.getDate(), 'h+': date.getHours() % 12, 'H+': date.getHours(), 'm+': date.getMinutes(), 's+': date.getSeconds(), 'q+': Math.floor((date.getMonth() + 3) / 3), 'S+': date.getMilliseconds(), 'W+': week[date.getDay()] }; if (/(y+)/.test(format)) format = format.replace( RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length) ); for (let k in o) if (new RegExp('(' + k + ')').test(format)) format = format.replace( RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length) ); return format; } /** * 将字符串时间转换为时间戳 * @param {string} date */ export function getDateTime(date) { let timestamp = ''; if (date) { date = date.substring(0, 19); date = date.replace(/-/g, '/'); //必须把日期'-'转为'/' timestamp = new Date(date).getTime(); } return timestamp; } /** * 获取年-月-日 * @data {Any} 时间戳 */ export function getDates(data) { let timeObj = {}; data = new Date(data); let y = data.getFullYear(); let m = data.getMonth() + 1 < 10 ? '0' + (data.getMonth() + 1) : data.getMonth() + 1; let d = data.getDate() < 10 ? '0' + data.getDate() : data.getDate(); let w = data.getDay(); switch (w) { case 1: w = '星期一'; break; case 2: w = '星期二'; break; case 3: w = '星期三'; break; case 4: w = '星期四'; break; case 5: w = '星期五'; break; case 6: w = '星期六'; break; case 7: w = '星期日'; break; } let h = data.getHours() < 10 ? '0' + data.getHours() : data.getHours(); let mi = data.getMinutes() < 10 ? '0' + data.getMinutes() : data.getMinutes(); let s = data.getSeconds() < 10 ? '0' + data.getSeconds() : data.getSeconds(); timeObj = { year: y + '', month: m + '', day: d + '', week: w + '', hour: h + '', minute: mi + '', second: s + '' }; return timeObj; } /** * 异常处理 * @param {boolean} condition * @param {string} msg */ export function assert(condition, msg) { if (!condition) throw new Error(`[Apior] ${msg}`); } /** * URL编码; * @param {参数} param */ export function toParams(param) { let result = ''; for (let name in param) { if (typeof param[name] != 'function') { if (param[name] === null) { result += '&' + name + '='; } else { result += '&' + name + '=' + encodeURI(param[name]); } } } return result.substring(1); } /** * 防抖函数 * @param fn 高频函数 * @param wait 等待时间 * @returns {Function} */ export function debounce(fn, wait) { let context = this, args = arguments, timer = null; return function() { context = this; args = arguments; clearTimeout(timer); timer = setTimeout(function() { fn.apply(context, args); }, wait || 250); }; } /** * 树形数据转换 * @param {*} data * @param {*} id * @param {*} pid */ export function treeDataTranslate(data) { // 删除 所有 children,以防止多次调用 data.forEach(function(item) { delete item.children; }); // 将数据存储为 以 id 为 KEY 的 map 索引数据列 var map = {}; data.forEach(function(item) { map[item.id] = item; }); // console.log(map); var val = []; data.forEach(function(item) { // 以当前遍历项,的pid,去map对象中找到索引的id var parent = map[item.pid]; // 好绕啊,如果找到索引,那么说明此项不在顶级当中,那么需要把此项添加到,他对应的父级中 if (parent) { (parent.children || (parent.children = [])).push(item); } else { //如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中,作为顶级 val.push(item); } }); return val; } /** * 对象深拷贝 * @param obj 对象 */ export function cloneObj(obj) { let str; let newObj = obj.constructor === Array ? [] : {}; if ( Object.prototype.toString.call(obj) !== '[object Object]' && Object.prototype.toString.call(obj) !== '[object Array]' ) { return; } else if (window.JSON) { str = JSON.stringify(obj); // 系列化对象 newObj = JSON.parse(str); // 还原 } else { for (let i in obj) { newObj[i] = typeof obj[i] === 'object' ? this.cloneObj(obj[i]) : obj[i]; } } return newObj; } /** * @function deepCopy 浅深拷贝 * @param {type} obj {description} * @return {type} {description} */ export function deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); } /** * 设置本地localStorage * @name {String} 数据对象的KEY * @data {all} 对应key的数据 */ export function setStorage(name, data) { let storage = window.localStorage; storage.setItem(name, JSON.stringify(data)); } /** * 拿到本地localStorage * @name {String} 数据对象的KEY */ export function getStorage(name) { let storage = window.localStorage; let data = JSON.parse(storage.getItem(name)); return data; } /** * 设置本地sessionStorage * @name {String} 数据对象的KEY * @data {all} 对应key的数据 */ export function setSessionStorage(name, data) { let storage = window.sessionStorage; storage.setItem(name, JSON.stringify(data)); } /** * 拿到本地sessionStorage * @name {String} 数据对象的KEY */ export function getSessionStorage(name) { let storage = window.sessionStorage; let data = JSON.parse(storage.getItem(name)); return data; } /** * 取出对象中制定属性返回新对象 * @obj {Object} 数据对象的KEY * @keys {Array} 数据对象的KEY */ export function certainProperty(obj, keys) { return keys.reduce((result, key) => { if (obj.hasOwnProperty(key)) { result[key] = obj[key]; } return result; }, {}); }
总结:以上是在公司总结出的比较有用的工具类,希望能对大家有些帮助,谢谢!