iview DatePicker 最近一周 最近一天 cookies函数 过期时间 使用自定义指令控制权限

本文分享了一系列实用的JavaScript工具函数,包括操作cookies、日期处理、时间范围选择、权限控制等,适用于各种前端项目需求。

Util.js是对常用函数的封装,方便在实际项目中使用。

保存cookies函数

module.exports = {

    /*
     功能:保存cookies函数
     参数:name, cookie名字; value, 值; time(天), 过期时间
     */
    setCookie: function (name, value, time) {
        var days = time;   //cookie 保存时间
        var exp = new Date();  //获得当前时间
        exp.setTime(exp.getTime() + days * 24 * 3600 * 1000);  //换成毫秒
        document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
    },
    /*
     功能:获取cookies函数
     参数:name, cookie名字
     */
    getCookie: function (name) {
        var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
        if (arr != null) {
            return unescape(arr[2]);
        } else {
            return null;
        }
    },
    /*
     功能:删除cookies函数
     参数:name, cookie名字
     */
    delCookie: function (name,domain) {
        var exp = new Date();  //当前时间
        exp.setTime(exp.getTime() - 1);//当前时间减去一,相当于立即过期(可以增减)
        var cval = this.getCookie(name);
        if (cval != null) document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString()+"; path=/;domain="+domain;////expires是对应过期时间的设置,不设这个值,cookie默认在关闭浏览器时失效
    }

}

获取两个日期之间的所有日期

// 获取两个日期之间的所有日期
getAllDate: function (begin, end) {
    let results = [];
    var ab = begin.split("-");
    var ae = end.split("-");
    var db = new Date();
    db.setUTCFullYear(ab[0], ab[1] - 1, ab[2]);
    var de = new Date();
    de.setUTCFullYear(ae[0], ae[1] - 1, ae[2]);
    var unixDb = db.getTime();
    var unixDe = de.getTime();
    for (var k = unixDb; k <= unixDe;) {
        results.push((new Date(parseInt(k))).format('yy-MM-dd'));
        k = k + 24 * 60 * 60 * 1000;
    }
    return results;
},

获取两个日期之间的所有小时

getAllDateHour: function (begin, end) {
    let results = [];
    var ab = begin.split("-");
    var ae = end.split("-");
    var db = new Date();
    db.setUTCFullYear(ab[0], ab[1] - 1, ab[2]);
    var de = new Date();
    de.setUTCFullYear(ae[0], ae[1] - 1, ae[2]);
    var unixDb = db.getTime();
    var unixDe = de.getTime();
    for (var k = unixDb; k <= unixDe;) {
        for (var i = 0; i < 24; i++) {
            if (i < 10) {
                results.push((new Date(parseInt(k))).format('yy-MM-dd') + " 0" + i+":00");
            } else {
                results.push((new Date(parseInt(k))).format('yy-MM-dd') + " " + i+":00");
            }
        }
        k = k + 24 * 60 * 60 * 1000;
    }
    return results;
},

获取初始化时间,默认最近一周

// 获取初始化时间,默认最近一周
getDefaultDate() {
  let start = this.getDays(-7);
  let end = this.getDays(0);
  start.setStart();
  end.setEnd();
  // let start = this.getHoursTime(-1);
  // let end = this.getHoursTime(0);
  start = this.timeFormate(start, 'yyyy-MM-dd hh:mm:ss');
  end = this.timeFormate(end, 'yyyy-MM-dd hh:mm:ss');
  this.selectDate = [start, end];
},
getHoursTime(hours) {
  const today = new Date().getTime();
  const date = new Date(today + (hours * 60 * 60 * 1000));
  return date;
},
// 初始化日期
getDays(days) {
  const today = new Date().getTime();
  const date = new Date(today + (days * 24 * 60 * 60 * 1000));
  return date;
},
formatDate(date, type) {
  const yy = date.getFullYear();
  const dateM = date.getMonth() + 1;
  const mm = dateM > 9 ? dateM : `0${dateM}`;
  const dateD = date.getDate();
  const dd = dateD > 9 ? dateD : `0${dateD}`;
  if (type) {
    return `${yy}${type}${mm}${type}${dd}`;
  }
  return `${yy}${mm}${dd}`;
},

获取当前时间上个月前12个月的第一天

//获取当前时间上个月前12个月的第一天
getCurrentMonthFirst(date){
  var date = new Date(date);
  date.setDate(1);
  var month = parseInt(date.getMonth() + 2);
  var day = date.getDate();
  if (month < 10) {
      month = '0' + month
  }
  if (day < 10) {
      day = '0' + day
  }
  return (date.getFullYear() - 1) + '-' + month + '-' + day;
},

获取当前时间上个月的最后一天

//获取当前时间上个月的最后一天
getCurrentMonthLast(date){
   var nowdays = new Date(date);
   var year = nowdays.getFullYear();
   var month = nowdays.getMonth();
   if(month==0){
       month=12;
       year=year-1;
   }
   if (month < 10) {
       month = "0" + month;
   }
   var lastDay = new Date(year, month, 0);
   var lastDayOfPreMonth = year + "-" + month + "-" + lastDay.getDate();//上个月的最后一天
   return lastDayOfPreMonth;
},

近一年的日期

// 近一年的日期
getPassYearFormatDate(date) {
  var nowDate = date;
  var date = new Date(nowDate);
  date.setDate(date.getDate()-365);
  var seperator1 = "-";
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  var strDate = date.getDate();
  if (month >= 1 && month <= 9) {
      month = "0" + month;
  }
  if (strDate >= 0 && strDate <= 9) {
      strDate = "0" + strDate;
  }
  var currentdate = year + seperator1 + month + seperator1 + strDate;
  return currentdate;
},

上个月的日期

// 上个月的日期
getPreMonth(date) {
  var arr = date.split('-');
  var year = arr[0]; //获取当前日期的年份
  var month = arr[1]; //获取当前日期的月份
  var day = arr[2]; //获取当前日期的日
  var days = new Date(year, month, 0);
  days = days.getDate(); //获取当前日期中月的天数
  var year2 = year;
  var month2 = parseInt(month) - 1;
  if (month2 == 0) {
      year2 = parseInt(year2) - 1;
      month2 = 12;
  }
  var day2 = day;
  var days2 = new Date(year2, month2, 0);
  days2 = days2.getDate();
  if (day2 > days2) {
      day2 = days2;
  }
  if (month2 < 10) {
      month2 = '0' + month2;
  }
  var t2 = year2 + '-' + month2 + '-' + day2;
  return t2;
},

vue iview table 点击表格行,触发checkbox

1、stopPropagation方法简言之,只能阻止父类元素的冒泡,
2、stopImmediatePropagation方法,简言之,既能阻止父类元素冒泡,也能阻止同类事件的执行。父元素不会执行同类事件,该元素执行完当前事件,绑定的同类事件也不会执行。
举例

setTimeout(() => { // 点击表格行,触发checkbox
 const trList = Array.from(document.getElementsByClassName('ivu-table-row'));
 console.log(trList);
 trList.forEach((tr) => {
   console.log(tr);
   tr.addEventListener('click', (e) => {
     e.stopImmediatePropagation();
     console.log(e);
     if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'A') {
       if (tr.getElementsByTagName('label')[0]) {
         const ttr = tr.getElementsByTagName('label')[0];
         console.log(ttr);
         ttr.click();
       }
     }
   });
 });
}, 500);

iview DatePicker options shortcuts 自定义时间范围

datePickOpt: {
  shortcuts: [
    {
      text: '最近一周',
      value() {
        const end = new Date();
        const start = new Date();
        start.setTime(start.getTime() - (3600 * 1000 * 24 * 7));
        return [start, end];
      },
    },
    {
      text: '最近一个月',
      value() {
        const end = new Date();
        const start = new Date();
        start.setTime(start.getTime() - (3600 * 1000 * 24 * 30));
        return [start, end];
      },
    },
    {
      text: '最近三个月',
      value() {
        const end = new Date();
        const start = new Date();
        start.setTime(start.getTime() - (3600 * 1000 * 24 * 90));
        return [start, end];
      },
    },
  ],
},
datePickOpt: {
  shortcuts: [
    {
      text: '最近两小时',
      value () {
        const end = new Date();
        const start = new Date();
        start.setTime(start.getTime() - (3600 * 1000 * 2));
        return [start, end];
      },
    },
    {
      text: '最近一天',
      value () {
        const end = new Date();
        const start = new Date();
        start.setTime(start.getTime() - (3600 * 1000 * 24));
        return [start, end];
      },
    },
    {
      text: '最近一周',
      value () {
        const end = new Date();
        const start = new Date();
        start.setTime(start.getTime() - (3600 * 1000 * 24 * 7));
        return [start, end];
      },
    },
  ],
},

JavaScript数组倒序函数reverse() 多次调用结果不一致

不能用reverse(), 因为数组是按引用传递的,要想多次运行得到一样的排列顺序,必须在某一地方打断引用传递

const chartDataRel = [];
// 倒序数据, 不能用reverse(), 因为数组是按引用传递的
for (let i = 0; i < chartData.length; i += 1) {
  chartDataRel[i] = chartData[chartData.length - i - 1];
}

下面的方法没有测试

const dataBeforeReverse = [...chartData];
const chartDataRel = dataBeforeReverse.reverse();

高精度权限控制自定义指令directive

我们通常给一个元素添加 v-if / v-show 来做权限管理,但如果判断条件繁琐且多个地方需要判断,这种方式的代码不仅不优雅而且冗余。
针对这种情况,我们可以通过全局自定义指令来处理:我们先在新建个 array.js 文件,用于存放与权限相关的全局函数:

// array.js
export function checkArray (key) {
  let arr = ['1', '2', '3', '4', 'demo']
  let index = arr.indexOf(key)
  if (index > -1) {
    return true // 有权限
  } else {
    return false // 无权限
  }
}

然后在将 array 文件挂载到全局中:

// main.js
  import { checkArray } from "./common/array";
  Vue.directive("permission", {
    inserted (el, binding) {
      let permission = binding.value; // 获取到 v-permission的值
      if (permission) {
        let hasPermission = checkArray(permission);
        if (!hasPermission) { // 没有权限 移除Dom元素
          el.parentNode && el.parentNode.removeChild(el);
        }
      }
    }
  });

最后我们在页面中就可以通过自定义指令 v-permission 来判断:

<div class="btns">
  <button v-permission="'1'">权限按钮1</button>  // 会显示
  <button v-permission="'10'">权限按钮2</button>  // 无显示
  <button v-permission="'demo'">权限按钮3</button> // 会显示
</div>
<think>我们使用iviewDatePicker组件时,可以通过设置`options`属性中的`disabledDate`函数来限制选择范围。要实现限制选择时间长度不超过30天,我们需要在日期选择器上设置一个动态的禁用规则。 具体思路: 1. 我们需要两个日期选择器(通常是开始日期和结束日期),分别绑定开始时间和结束时间。 2. 在开始日期的选择器上,我们限制不能选择结束日期后30天之后的日期(同时也要限制不能选择结束日期之后的日期,但这里主要是30天的限制)。 3. 在结束日期的选择器上,我们限制不能选择开始日期前30天之前的日期(同时不能选择开始日期之前的日期)。 但是,请注意,通常我们限制的是:选择的日期范围不能超过30天。这里有两种情况: - 先选择开始日期,则结束日期只能选择开始日期之后30天内的日期。 - 先选择结束日期,则开始日期只能选择结束日期之前30天内的日期。 因此,我们需要在两个日期选择器上相互制约。 然而,iviewDatePicker组件提供了两种方式:单个选择器(选择范围)和两个选择器(分别选择开始和结束)。根据你的需求,你可能使用的是两个独立的DatePicker(一个开始,一个结束),也可能使用一个RangePicker(范围选择器)。 下面分别给出两种情况的实现: ### 情况1:使用两个独立的DatePicker(开始日期和结束日期) 模板部分: ```html <template> <div> <DatePicker type="date" v-model="startDate" placeholder="选择开始日期" :options="startOptions" @on-change="handleStartChange" ></DatePicker> <DatePicker type="date" v-model="endDate" placeholder="选择结束日期" :options="endOptions" @on-change="handleEndChange" ></DatePicker> </div> </template> ``` 脚本部分: ```javascript data() { return { startDate: '', endDate: '', // 开始日期的禁用规则 startOptions: { disabledDate: (date) => { // 如果结束日期已经选择,则开始日期不能大于结束日期,也不能小于结束日期前推30天 if (this.endDate) { // 计算结束日期前30天 const limitStart = new Date(this.endDate); limitStart.setDate(limitStart.getDate() - 30); // 开始日期只能选择在结束日期前30天到结束日期之间 return date > new Date(this.endDate) || date < limitStart; } // 如果结束日期没有选择,则不做限制(或者根据需求调整) return false; } }, // 结束日期的禁用规则 endOptions: { disabledDate: (date) => { if (this.startDate) { const limitEnd = new Date(this.startDate); limitEnd.setDate(limitEnd.getDate() + 30); // 结束日期不能小于开始日期,也不能大于开始日期后30天 return date < new Date(this.startDate) || date > limitEnd; } return false; } } }; }, methods: { handleStartChange(start) { this.startDate = start; // 如果开始日期改变,且结束日期存在并且开始日期大于结束日期,则重置结束日期 if (this.endDate && new Date(start) > new Date(this.endDate)) { this.endDate = ''; } }, handleEndChange(end) { this.endDate = end; // 如果结束日期改变,且开始日期存在并且结束日期小于开始日期,则重置开始日期 if (this.startDate && new Date(end) < new Date(this.startDate)) { this.startDate = ''; } } } ``` ### 情况2:使用RangePicker(范围选择器) 如果使用范围选择器,则在一个选择器内选择开始和结束日期。 模板部分: ```html <template> <DatePicker type="daterange" v-model="dateRange" placeholder="选择日期范围" :options="rangeOptions" ></DatePicker> </template> ``` 脚本部分: ```javascript data() { return { dateRange: [], // [startDate, endDate] rangeOptions: { disabledDate: (date) => { // 这里我们无法直接限制范围不超过30天,因为选择是分两次的,所以我们需要在选中后判断,但禁用规则可以动态调整 // 但是,我们可以通过禁用30天以外的日期来达到目的,但是需要知道当前选中的临时开始日期 // 然而,iview在范围选择器中,当选择第一个日期后,第二个日期的禁用规则会基于第一个日期动态调整 // 所以我们可以这样:如果已经选择了一个日期(临时开始日期),那么另一个日期只能在这个日期的前后30天内 // 但是注意,我们这里要限制总跨度不超过30天,所以第二个日期只能在第一个日期之后的30天内选择,同时也不能在之前选择(因为范围选择器默认是开始到结束,所以开始日期一定在结束日期前) // 实际上,我们可以这样:在还没有选择任何日期时,不禁用;当选择了第一个日期(临时值)后,第二个日期只能从第一个日期到第一个日期+30天 // 由于iview的范围选择器在内部会记录临时值,我们可以通过this.dateRange[0]获取开始日期 const startDate = this.dateRange[0] ? new Date(this.dateRange[0]) : null; if (startDate) { const minDate = new Date(startDate); const maxDate = new Date(startDate); maxDate.setDate(maxDate.getDate() + 30); // 如果当前日期在minDate之前,或者在maxDate之后,则禁用 return date < minDate || date > maxDate; } return false; } } }; } ``` 但是,上述范围选择器的做法有一个问题:用户可能先选择结束日期,再选择开始日期。而iview的范围选择器选择顺序是固定的:先选开始,再选结束。所以上述方法可行。 然而,在实际使用中,我们还需要注意:如果用户先选择了一个结束日期(实际上在范围选择器中,用户先选择的会被认为是开始日期),所以不用担心顺序。 但是,我们需要在用户选择后检查,如果范围超过30天,则自动调整结束日期为开始日期+30天?或者提示用户?这里我们只是通过禁用日期来限制用户选择。 另外,上述范围选择器的做法在用户选择开始日期后,结束日期只能选择30天内的日期,但是用户如果想要重新选择开始日期,此时结束日期已经被清空(因为范围选择器在重新选择时会清空),所以需要重新选择。或者我们可以通过其他方式保留结束日期?但实际上,iview的范围选择器在重新选择时会重置。 因此,我们也可以选择在用户选择完成后,通过校验来判断是否超过30天,如果超过则提示并重置。 这里我们展示的是通过禁用日期来限制。 ### 注意事项 1. 在禁用日期函数中,我们返回`true`表示禁用该日期。 2. 日期对象比较:注意`date`参数是Date对象,我们比较时也要用Date对象。 3. 在情况1中,我们使用了两个单独的DatePicker,所以在开始日期变化时,我们需要检查结束日期是否合法(比如开始日期大于结束日期,则重置结束日期),同样结束日期变化时检查开始日期。 以上是两种实现方式,你可以根据你的具体场景选择。 另外,iview官方文档中也有类似的示例:限制选择日期范围。我们可以参考官方文档中的[DatePicker的options.disabledDate](https://www.iviewui.com/components/date-picker)。 最后,如果需求是要求选择的日期范围不能超过30天,那么使用范围选择器(RangePicker)可能更合适,因为用户一次操作就可以选择两个日期,且禁用规则可以动态调整。 希望这些方法能帮助你解决问题。 §§相关问题§§ 1. iview中如何限制DatePicker只能选择今天及之前的日期? 2. iview DatePicker如何禁用周末? 3. iview RangePicker如何设置默认日期范围? </think>在 iViewDatePicker 中限制选择时间长度不超过 30 天的实现方法如下: ### 核心实现方案 - 使用 `disabledDate` 函数 ```vue <template> <DatePicker type="daterange" v-model="dateRange" :options="pickerOptions" placeholder="请选择日期范围" ></DatePicker> </template> <script> export default { data() { return { dateRange: [], // 保存选择的日期范围 [startDate, endDate] pickerOptions: { disabledDate: (date) => { // 如果没有选择开始日期,不禁用任何日期 if (!this.dateRange[0]) return false; // 计算30天前后的边界日期 const start = new Date(this.dateRange[0]); const minDate = new Date(start); minDate.setDate(minDate.getDate() - 30); const maxDate = new Date(start); maxDate.setDate(maxDate.getDate() + 30); // 禁用30天范围外的日期 return date < minDate || date > maxDate; } } }; } }; </script> ``` ### 代码解析 1. **daterange 类型** - 使用 `type="daterange"` 启用范围选择模式 - 自动生成两个日期选择框(开始日期和结束日期) 2. **disabledDate 函数** - 核心限制逻辑在此函数中实现 - 根据已选的开始日期动态计算30天边界 - 使用 `setDate()` 方法进行日期加减计算[^1] 3. **边界日期计算** ```javascript const minDate = new Date(start); minDate.setDate(minDate.getDate() - 30); // 开始日期前30天 const maxDate = new Date(start); maxDate.setDate(maxDate.getDate() + 30); // 开始日期后30天 ``` 4. **禁用规则** ```javascript return date < minDate || date > maxDate; ``` - 所有在30天范围外的日期都会被禁用 - 选择开始日期后,结束日期只能选30天内的日期 ### 动态效果说明 1. **初始状态**:未选择日期时,所有日期可选 2. **选择开始日期后**:自动限制结束日期只能选择: - 开始日期前30天内 **或** - 开始日期后30天内 3. **重置功能**:清空选择后恢复全部可选 ### 替代方案 - 使用确认时验证 ```javascript // 在提交表单时验证 validateDateRange() { if (this.dateRange.length !== 2) return false; const diff = Math.abs( new Date(this.dateRange[1]) - new Date(this.dateRange[0]) ); const days = diff / (1000 * 60 * 60 * 24); if (days > 30) { this.$Message.error('选择范围不能超过30天'); return false; } return true; } ``` ### 注意事项 1. **时区处理**: - 使用本地日期对象 `new Date()` - 确保服务器和客户端时区一致 2. **跨月/年处理**: - `setDate()` 自动处理跨月跨年[^1] - 示例:1月1日前推30天 → 12月2日 3. **UI反馈**: - 可添加提示文本:"最大选择范围:30天" - 使用 `$Message` 显示错误提示
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值