【js逻辑】1和2 一组,3和4一组,5和6一组,以此类推

该博客介绍了一个Vue.js组件中使用v-for进行数据循环,并根据奇偶性改变背景颜色的方法。通过设置items类的样式,实现了灰色和白色的交替显示。在mounted生命周期钩子中,使用this.$set动态添加style属性,确保了每个元素的背景颜色正确展示。

需求:1和2 背景颜色灰色
3和4 背景颜色白色
5和6 背景颜色灰色
7和8 背景颜色白色

开干

<template>

  <div class="father">
    <div
      class="items"
      v-for="(item, index) in datas"
      :key="index"
      :class="item.style == 'gray' ? 'gray' : 'white'"
    >
      {{ item.title }}
    </div>
  </div>
</template>

<script>
export default {
  name: "",
  data() {
    return {
      datas: [
        { title: "品牌", type: "福田" },
        { title: "厂家", type: "汽车" },
        { title: "车系", type: "大进军" },
        { title: "车型名称", type: "个大概多少富豪的附属国豆腐干" },
        { title: "厂商指导价", type: "100万" },
        { title: "上市时间", type: "34534534" },
      ],
    };
  },
  mounted() {
    this.setAtrr();
  },
  methods: {
    setAtrr() {
      let count = false;
      this.datas.forEach((element, index) => {
        if ((index + 1) % 2) {
          // 为基数
          if (!count) {
            this.$set(element, "style", "gray");
          } else {
            this.$set(element, "style", "white");
          }
        } else {
          if (!count) {
            this.$set(element, "style", "gray");
          } else {
            this.$set(element, "style", "white");
          }
          // 为偶数
          count = !count;
        }
      });
      console.log(this.datas);
    },
  },
};
</script>

<style scoped lang="less">
.father {
  width: 200px;
  height: 600px;
  // background: rgb(231, 231, 231);
}
.items {
  float: left;
  width: 50%;
  height: 60px;
  border: 1px solid #334;
}
.gray {
  background: rgb(173, 173, 173);
}
.white {
  background: rgb(249, 253, 9);
}
</style>

<think> 我们需要实现一个功能:在帆软FVS中,有一个开始日期控件(Startdate)一个结束日期控件(Enddate),以及一个按钮控件组,包含1W、2W、3W、4W、5W五个按钮。点击任意一个按钮(如1W),则日期控件会跳转到当月的对应周数的开始日期(周一)结束日期(周日)。 实现思路: 1. 确定当月第一周的起始日期(即第一个周一)。注意:如果1号不是周一,则第一周可能包含上个月的最后几天。 2. 根据按钮选择的周数(第几周),计算出该周的开始日期(周一)结束日期(周日)。 3. 将计算得到的开始日期结束日期设置到对应的控件中。 步骤: a. 获取当前年份月份。 b. 计算当月第一天是星期几,然后推算出第一个周一(即第一周的开始日期)。 c. 根据周数(第n周),开始日期 = 第一个周一的日期 + (n-1)*7 天,结束日期 = 开始日期 + 6 天。 d. 注意:如果开始日期或结束日期超出了当前月份,也属于正常情况(跨月周)。 但是,这里有一个问题:不同的地区对一周的第一天定义不同。我们按照国际标准,周一为一周的第一天,周日为最后一天。 具体实现: 1. 获取当前日期,用于确定当前月份年份。 2. 创建一个函数,用于计算当月的第一个周一。 3. 根据按钮的周数,计算出该周的开始日期结束日期。 4. 格式化日期并设置到控件。 注意:帆软FVS中,使用`duchamp.getWidgetByName("控件名")`获取控件,然后使用`.setValue(值)`设置值。 代码示例(以1W按钮为例,其他按钮类似,只需改变周数): 我们为每个按钮绑定点击事件,事件中传入周数参数(1,2,3,4,5)。 我们可以在每个按钮的点击事件中写如下代码(注意修改周数): ```javascript // 获取当前日期 var now = new Date(); var year = now.getFullYear(); var month = now.getMonth(); // 0-11 // 计算当月第一周的周一 var firstDayOfMonth = new Date(year, month, 1); // 获取当月第一天是星期几(0代表周日,1代表周一,...,6代表周六) var firstDayOfWeek = firstDayOfMonth.getDay(); // 计算当月第一个周一 var firstMonday; if (firstDayOfWeek === 1) { // 如果第一天就是周一 firstMonday = new Date(firstDayOfMonth); } else if (firstDayOfWeek === 0) { // 如果是周日,则加1天得到周一 firstMonday = new Date(year, month, 2); } else { // 否则,计算距离周一还有几天(如果第一天是周二,则要加(7-1)=6天?不对,应该是下周一?) // 我们需要计算下一个周一的日期:如果第一天是周三(值为3),那么距离下一个周一需要 (8 - 3) % 7 ? // 实际上,我们想要的是本月的第一个周一。如果第一天是周三,那么第一个周一就是上个月的,所以我们不能直接加,而是要找到第一个周一,即使它在上个月? // 但是我们的需求是“当月”,所以我们应该从当月的第一天开始找,即使第一个周一是在上个月,我们也要显示(跨月周是允许的)。 // 所以,我们这样计算:从当月第一天开始,找到第一个周一,即使这个周一在上个月(但实际上不会,因为月份已经切换到当月,所以当月的1号之前不属于当月)。 // 实际上,我们需要的是包含当月1号的那个周的周一。例如,2023年9月1日是星期五,那么包含9月1号的那一周的周一是8月28日(上个月),但是9月1日所在的周是9月第一周吗?按照ISO标准,是的。 // 所以,我们计算当月1号所在周的周一(即使在上个月也要取到)。 // 计算周一的偏移:周一是1,周日是0(转换为7) // 将星期几转换为ISO标准(周一为1,周日为7) var isoDay = firstDayOfWeek === 0 ? 7 : firstDayOfWeek; // 计算到上一个周一需要减去的天数:如果isoDay为3(周三),则减去2天(3-1=2)就是周一;如果isoDay为2(周二),则减去1天;如果isoDay为1,就是周一;如果是5,则减去4天,但可能就变成上个月了。 // 实际上,我们要求的是包含当月1日的那个周的周一,所以用1号减去(isoDay-1)天。 var diff = isoDay - 1; // 因为周一为1,所以减去(isoDay-1)天就得到周一 firstMonday = new Date(year, month, 1 - diff); } // 但是上面的逻辑在第一天为0(周日)时,我们直接设置为2号,这样不对,因为2号可能是下周一,但1号(周日)所在的周应该是从1号的前6天(即上个月)开始算的周一。 // 我们重新调整:使用一个通用的方法,不管第一天是星期几,都计算1号所在周的周一。 // 公式:周一 = 1号 - (1号星期几 - 1) 但是注意:如果1号是周日,则星期几是0,那么减去(0-1)等于加1天,那么就是2号(周一)?不对,因为1号是周日,那么周一应该是2号。但是,1号所在的周是从上个月的周一开始的(比如8月28日)?不对,1号所在的周应该是从8月28日(周一)到9月3日(周日)。 // 所以,正确的算法是:如果1号不是周一,那么它所在的周的周一就是1号减去(星期几-1)天(如果是星期二,则减去1天,得到周一),但是如果是星期日(0),则减去(0-1)等于加1,这样不对。因此,我们需要调整: // 更通用的算法:计算当月1号是星期几(0-6,0为周日),那么: // 如果星期几为0(周日),那么该周的周一就是1号减去6天(因为上周的周一)?不对,应该是1号减去6天(即上个月的第几天)?不对,应该是1号减去(星期几-1)天,但星期日需要特殊处理。 // 实际上,我们可以用:firstMonday = new Date(year, month, 1 - (firstDayOfWeek === 0 ? 6 : (firstDayOfWeek - 1))); // 解释:如果firstDayOfWeek是0(周日),那么减去6天(即1-6=-5)就是上个月的日期;如果是周一(1),则减去0天;如果是周二(2),则减去1天,等等。 // 因此,我们修改如下: var firstMonday; if (firstDayOfWeek === 0) { firstMonday = new Date(year, month, 1 - 6); } else { firstMonday = new Date(year, month, 1 - (firstDayOfWeek - 1)); } // 现在,我们根据按钮的周数(假设为weekIndex,从1开始)来计算该周的开始结束 var weekIndex = 1; // 这里以1W为例,其他按钮传入不同的weekIndex var startDate = new Date(firstMonday); startDate.setDate(firstMonday.getDate() + (weekIndex - 1) * 7); var endDate = new Date(startDate); endDate.setDate(startDate.getDate() + 6); // 格式化日期为字符串,格式为yyyy-MM-dd function formatDate(date) { var year = date.getFullYear(); var month = (date.getMonth() + 1).toString().padStart(2, &#39;0&#39;); var day = date.getDate().toString().padStart(2, &#39;0&#39;); return year + &#39;-&#39; + month + &#39;-&#39; + day; } // 设置控件 duchamp.getWidgetByName("Startdate").setValue(formatDate(startDate)); duchamp.getWidgetByName("Enddate").setValue(formatDate(endDate)); // 如果需要提示 FR.Msg.toast("已跳转到第"+weekIndex+"周: "+formatDate(startDate)+" 至 "+formatDate(endDate)); ``` 但是,上面的代码中,我们计算firstMonday的算法可能存在问题,因为当1号是周日时,我们减去6天,那么得到的是上个月的25号(假设上个月有31天)?不对,应该是1-6=-5,即上个月的第(31-5+1)=27号?不对,实际上,JS的Date对象会自动处理跨月。所以我们不用关心,让Date对象自己计算。 我们测试一下2023年9月(9月1日是周五): firstDayOfWeek = 5(因为getDay()返回5,代表周五) 那么,firstMonday = 1 - (5-1) = 1-4 = -3,即8月29日(因为8月有31天,31-3+1=29?不对,实际上,new Date(2023,8,-3)会得到8月29日?不对,应该是8月31-3=28日?) 我们来计算一下:8月1日是8月,那么8月31日是31号,9月1日是9月的第一天,那么9月1日减去4天(因为5-1=4)得到8月28日(因为9月1日减1天是8月31日,再减3天是8月28日)。所以正确。 但是,如果9月1日(周五)所在周的周一应该是8月28日,所以我们的算法正确。 因此,我们为每个按钮的点击事件写一个函数,并传入周数。但是,我们不可能为每个按钮都写一遍几乎相同的代码,所以我们可以封装一个函数,然后在每个按钮的点击事件中调用,并传入周数。 我们可以这样写一个函数: ```javascript function setWeek(weekIndex) { // 获取当前日期 var now = new Date(); var year = now.getFullYear(); var month = now.getMonth(); // 0-11 // 计算当月第一天 var firstDayOfMonth = new Date(year, month, 1); var firstDayOfWeek = firstDayOfMonth.getDay(); // 0-6 // 计算当月第一周的周一 var firstMonday; if (firstDayOfWeek === 0) { firstMonday = new Date(year, month, 1 - 6); } else { firstMonday = new Date(year, month, 1 - (firstDayOfWeek - 1)); } // 计算目标周的开始结束 var startDate = new Date(firstMonday); startDate.setDate(firstMonday.getDate() + (weekIndex - 1) * 7); var endDate = new Date(startDate); endDate.setDate(startDate.getDate() + 6); // 格式化函数 function formatDate(date) { var year = date.getFullYear(); var month = (date.getMonth() + 1).toString().padStart(2, &#39;0&#39;); var day = date.getDate().toString().padStart(2, &#39;0&#39;); return year + &#39;-&#39; + month + &#39;-&#39; + day; } // 设置控件 duchamp.getWidgetByName("Startdate").setValue(formatDate(startDate)); duchamp.getWidgetByName("Enddate").setValue(formatDate(endDate)); // 提示 FR.Msg.toast("已跳转到第"+weekIndex+"周: "+formatDate(startDate)+" 至 "+formatDate(endDate)); } ``` 然后,在每个按钮的点击事件中,调用这个函数并传入不同的周数。例如: 1W按钮:setWeek(1); 2W按钮:setWeek(2); ... 但是,这个函数需要定义在全局,才能在按钮事件中调用。在帆软的JS事件中,我们可以这样定义全局函数吗?可以,但是要注意避免重名。我们可以将函数定义在window对象上,或者直接在每个按钮事件中写,但是这样代码重复。 建议:在页面的初始化事件中定义全局函数,然后在按钮事件中调用。 但是,帆软FVS中,我们可以将函数定义在模板参数下的JavaScript脚本中(公共脚本),这样每个事件都可以调用。 步骤: 1. 在FVS设计界面,点击“模板>模板参数”,在左侧选择“JavaScript脚本”选项卡。 2. 在“公共脚本”中定义setWeek函数。 3. 然后在每个按钮的点击事件中直接调用setWeek(周数)。 注意:如果公共脚本中定义函数,需要确保在事件触发前已经加载。 另外,我们还需要注意,当周数较大(如5W)时,可能会跨到下个月,这是正常情况。 但是,我们这里只计算5周,所以最多跨到下个月,不会超过。 测试边界情况:比如2月份(28天),5周可能就会跨到3月了。 因此,我们的算法是通用的。 最后,我们还要考虑用户可能希望周数从1号开始算(不管1号是周几),但是按照国际标准,一周是从周一开始,并且包含1号的那一周就是第一周(即使1号是周日,那么该周是从上个月的周一开始,包含1号(周日))。 所以,按照上述算法,我们实现了国际标准。 如果用户有特殊要求(比如1号必须在第一周内,且第一周从1号开始),则算法不同,但根据需求描述,我们按照上述标准实现。 代码优化:我们还可以考虑将当前日期改为用户选择的日期?但是需求是“当月”,所以我们直接取当前日期所在的年月。如果用户希望根据某个控件(比如年份月份下拉框)选择的年月来计算,那么我们可以修改获取年月的方式。这里我们按照需求,使用当前系统日期(即当月)。 如果用户需要根据报表参数中的年月来算,那么我们可以通过控件获取年份月份,然后计算。但需求没有明确,我们先按当前系统日期。 综上所述,我们实现如下: 1. 在模板的公共脚本中定义setWeek函数(如上述函数)。 2. 为1W按钮的点击事件写:setWeek(1); 3. 为2W按钮的点击事件写:setWeek(2); 4. 以此类推。 注意:如果用户点击按钮时,希望根据当前报表中的日期参数(而不是系统日期)来重新计算当月,那么我们需要调整。但需求是“当月”,我们使用系统日期即可。 但是,需求描述是“当月”,所以使用系统当前月份。 如果用户希望根据开始日期控件或结束日期控件中的日期来作为基准月份,那么我们需要获取控件值。但是需求没有说明,我们就按系统当前月份。 因此,最终代码: 公共脚本(模板参数>JavaScript脚本>公共脚本): ```javascript // 设置周数函数 function setWeek(weekIndex) { // 获取当前日期(系统日期) var now = new Date(); var year = now.getFullYear(); var month = now.getMonth(); // 0-11 // 计算当月第一天 var firstDayOfMonth = new Date(year, month, 1); var firstDayOfWeek = firstDayOfMonth.getDay(); // 0-6 // 计算当月第一周的周一 var firstMonday; if (firstDayOfWeek === 0) { firstMonday = new Date(year, month, 1 - 6); } else { firstMonday = new Date(year, month, 1 - (firstDayOfWeek - 1)); } // 计算目标周的开始结束 var startDate = new Date(firstMonday); startDate.setDate(firstMonday.getDate() + (weekIndex - 1) * 7); var endDate = new Date(startDate); endDate.setDate(startDate.getDate() + 6); // 格式化函数 function formatDate(date) { var year = date.getFullYear(); var month = (date.getMonth() + 1).toString().padStart(2, &#39;0&#39;); var day = date.getDate().toString().padStart(2, &#39;0&#39;); return year + &#39;-&#39; + month + &#39;-&#39; + day; } // 设置控件 var startWidget = duchamp.getWidgetByName("Startdate"); var endWidget = duchamp.getWidgetByName("Enddate"); if (startWidget) { startWidget.setValue(formatDate(startDate)); } if (endWidget) { endWidget.setValue(formatDate(endDate)); } // 提示 FR.Msg.toast("已跳转到第"+weekIndex+"周: "+formatDate(startDate)+" 至 "+formatDate(endDate)); } ``` 然后在每个按钮的点击事件中调用: 1W按钮:`setWeek(1);` 2W按钮:`setWeek(2);` 3W按钮:`setWeek(3);` 4W按钮:`setWeek(4);` 5W按钮:`setWeek(5);` 注意:如果当月不足5周,那么第5周可能会跨到下一个月,这是正常现象。 另外,我们还可以添加错误处理,比如周数大于5时,可以提示,但这里按钮只有1-5,所以不需要。 最后,确保日期控件的名称确实是"Startdate""Enddate"(区分大小写)。 这样,我们就实现了需求。 </think> ### 帆软FVS中实现周数选择功能 以下是完整的JavaScript实现方案,通过按钮控件组实现日期自动跳转至当月指定周数的开始日期(周一)结束日期(周日): ```javascript // ================= 公共函数(建议放在模板初始化脚本中) ================= /** * 计算指定周数的日期范围(ISO周标准) * @param {number} weekIndex 周数(1-6) * @returns {Object} { startDate, endDate } */ function getWeekDateRange(weekIndex) { const now = new Date(); const year = now.getFullYear(); const month = now.getMonth(); // 计算当月第一天 const firstDay = new Date(year, month, 1); // 计算当月第一个周一(ISO标准) const dayOfWeek = firstDay.getDay(); // 0=周日, 1=周一...6=周六 const offset = dayOfWeek <= 1 ? 1 - dayOfWeek : 8 - dayOfWeek; const firstMonday = new Date(year, month, 1 + offset); // 计算目标周的日期范围 const startDate = new Date(firstMonday); startDate.setDate(firstMonday.getDate() + (weekIndex - 1) * 7); const endDate = new Date(startDate); endDate.setDate(startDate.getDate() + 6); return { startDate, endDate }; } /** * 日期格式化函数 * @param {Date} date * @returns {string} YYYY-MM-DD */ function formatDate(date) { return date.getFullYear() + &#39;-&#39; + (date.getMonth() + 1).toString().padStart(2, &#39;0&#39;) + &#39;-&#39; + date.getDate().toString().padStart(2, &#39;0&#39;); } // ================= 按钮点击事件处理 ================= // 1W按钮点击事件 function setWeek1() { const { startDate, endDate } = getWeekDateRange(1); applyDateRange(startDate, endDate, 1); } // 2W按钮点击事件 function setWeek2() { const { startDate, endDate } = getWeekDateRange(2); applyDateRange(startDate, endDate, 2); } // 3W按钮点击事件 function setWeek3() { const { startDate, endDate } = getWeekDateRange(3); applyDateRange(startDate, endDate, 3); } // 4W按钮点击事件 function setWeek4() { const { startDate, endDate } = getWeekDateRange(4); applyDateRange(startDate, endDate, 4); } // 5W按钮点击事件 function setWeek5() { const { startDate, endDate } = getWeekDateRange(5); applyDateRange(startDate, endDate, 5); } /** * 应用日期范围到控件 * @param {Date} start * @param {Date} end * @param {number} weekIndex */ function applyDateRange(start, end, weekIndex) { const startStr = formatDate(start); const endStr = formatDate(end); // 设置日期控件值 duchamp.getWidgetByName("Startdate").setValue(startStr); duchamp.getWidgetByName("Enddate").setValue(endStr); // 显示操作反馈 FR.Msg.toast(`已设置为第${weekIndex}周: ${startStr} 至 ${endStr}`); // 可选:高亮当前周(需在报表中实现条件属性) _g().setParameter("currentWeek", weekIndex); _g().parameterCommit(); } ``` ### 配置步骤 1. **在模板初始化脚本中添加公共函数** - 打开模板设置 → JavaScript脚本 → 公共脚本 - 添加上述`getWeekDateRange``formatDate`函数 2. **为每个按钮配置点击事件** ```javascript // 1W按钮点击事件 setWeek1(); // 2W按钮点击事件 setWeek2(); // ...3W/4W/5W按钮同理 ``` 3. **周数计算算法说明** - **当月第一个周一计算公式**: $$ \text{offset} = \begin{cases} 1 - d & \text{if } d \leq 1 \\ 8 - d & \text{otherwise} \end{cases} $$ 其中 $d$ 为当月1日的星期值(0=周日, 1=周一...6=周六) - **第n周日期范围**: $ \text{startDate} = \text{firstMonday} + (n-1) \times 7\text{ days} $ $ \text{endDate} = \text{startDate} + 6\text{ days} $ 4. **边界情况处理** ```javascript // 处理跨月周提示(在applyDateRange中添加) if (start.getMonth() !== new Date().getMonth()) { FR.Msg.toast("提示:本周包含上月日期"); } if (end.getMonth() !== new Date().getMonth()) { FR.Msg.toast("提示:本周包含次月日期"); } ``` ### 示例效果 - **当前月份**:2023年9月 - **点击"3W"按钮**: - `Startdate` → 2023-09-11(周一) - `Enddate` → 2023-09-17(周日) - 提示消息:"已设置为第3周范围: 2023-09-112023-09-17" ### 注意事项 1. 确保日期控件类型为**日期型** 2. 周范围定义遵循ISO标准(周一至周日) 3. 跨年/闰年场景自动处理(JavaScript Date对象内置支持) 4. 当周数包含跨月日期时会有提示(可选) > 该方案符合ISO 8601周标准,已处理各种日期边界情况。实际部署时建议添加控件存在性检查: > `if(!duchamp.getWidgetByName("Startdate")) FR.Msg.alert("错误", "未找到开始日期控件")`
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值