2025-35st-w-日常开发总结

acro-design a-table 行选择以及禁止某一行筛选

xml 复制代码
// 通过某一行的slotName可以给record设置disabled 
<template #status="{ record }">
  <!--表格数据设置disabled:true,就不会被选中-->
  <a-badge
    :dis="
      !canSubmitBlockStatus.includes(record.status)
        ? (record.disabled = true)
        : ''
    "
  />
</template>
//再配合
@selectchange="handleSelect"【选择行事件】  以及
:selected-keys="state.selectedRows"//选择行的index
:row-selection="rowSelection"//是否开启行选择

倒计时

ini 复制代码
// 倒计时, 传入服务器时间,以及告警时间, 结束时间
import { ref, computed } from "vue";

export function countDownWith3Time(
  serverTime,
  warnTime,
  overTime,
  improveTime = undefined,
  status
) {
  if (serverTime === undefined || serverTime === null) {
    return { text: "", color: "black" };
  }
  let countdown;
  countdown = computed(() => {
    let ct = ref({ text: "", color: "black" });
    const initialClientTime = Date.now();
    const initialServerTime = new Date(serverTime).getTime();
    const warnTimeMs = new Date(warnTime).getTime();
    const overTimeMs = new Date(overTime).getTime();
    const improveTimeMs = new Date(improveTime).getTime();
    let timerId = null;

    function formatTime(ms) {
      if (ms <= 0) {
        return { h: 0, m: 0, s: 0 };
      }
      const totalSeconds = Math.floor(ms / 1000);
      const h = Math.floor(totalSeconds / 3600);
      const m = Math.floor((totalSeconds % 3600) / 60);
      const s = totalSeconds % 60;
      return { h, m, s };
    }

    function update() {
      // 如果存在improveTime,就表示需要判断是按时完善还是超时完善
      if (improveTimeMs > 0 && status === 1) {
        if (improveTimeMs <= overTimeMs) {
          ct.value.text = "按时完善";
          ct.value.color = "green";
        } else {
          ct.value.text = "超时完善";
          ct.value.color = "red";
        }
        stop();
        return;
      }
      const currentClientTime = Date.now();
      const elapsed = currentClientTime - initialClientTime;
      const currentServerTime = initialServerTime + elapsed;

      if (currentServerTime >= overTimeMs) {
        ct.value.text = "已超时";
        ct.value.color = "red";
        stop();
        return;
      }

      let color = "black";
      if (currentServerTime >= warnTimeMs) {
        color = "orange";
      }

      const remaining = overTimeMs - currentServerTime;
      const { h, m, s } = formatTime(remaining);
      ct.value.text = [
        h.toString().padStart(2, "0"),
        m.toString().padStart(2, "0"),
        s.toString().padStart(2, "0")
      ].join(":");
      ct.value.color = color;
    }

    function stop() {
      if (timerId) {
        clearInterval(timerId);
        timerId = null;
      }
    }

    timerId = setInterval(update, 1000);
    update(); // 立即执行初始化
    return { ct, stop };
  });
  return countdown;
}

dom.scrollTo({x:0, y:0})

第二种用法:只支持 { behavior: "smooth", top/left: 0 只有left 跟top }

acro-design a-table 自定义表头

xml 复制代码
<template #title>
  <div
    v-if="item.slotName === 'ws_status'"
    //具体表头的定义
    style="display: flex; align-items: center"
  >
    <span>{{ item.title }}</span>
    <a-popover class="pop-content">
      <img :src="questionMark" alt="问号" style="margin-left: 130px" />
      <template #content>
        <span class="pop-title">警情各模块完善情况</span>
        <div
          style="
            display: flex;
            align-items: center;
            gap: 12px;
            margin-top: 6px;
          "
        >
          <img :src="no" alt="待完善" />
          待完善
        </div>
        <div
          style="
            display: flex;
            align-items: center;
            gap: 12px;
            margin-top: 6px;
          "
        >
          <img :src="yes" alt="已完善" />
          已完善
        </div>
      </template>
    </a-popover>
  </div>
  <span v-else>{{ item.title }}</span>
</template>

#其他总结 acro-design a-form 方法 resetFields(), 必须在a-form-item 上设置field 才有效

scss 复制代码
table-layout: fixed;
//  这里设置auto,单元格宽度由内容决定。 fixed就是由表头宽度决定

//acro-design a-modal onBeoreOk,点击ok按钮前事件

const onBeforeOk = async (done) => {
  if (xxx) {
    done(false);//这里表示阻止弹窗关闭
  } else {
    const temp = cloneDeep(state.form);
    const res = await setSub(temp); //这里必须异步等待执行完毕之后,在调用done(true)
    if (res.data) {
      $message.success("配置修改成功!");
      emit("refresh"); 
    }
    done(true);
  }
};
// 如果同时还绑了@ok,在ok里执行emit("refresh"); 不会生效。必须在onBeforeOk才可以

大屏开发

·1· 酷炫的文字和容器边框都采用图片的形式呈现比较简单。

·2· 点击全屏功能可以使用 screenFull.js

·3· 所有的单位都尽量使用vh vw 包括文字大小

·4· 图表组件 vue-charts 文档 github.com/ecomfe/vue-...

·5· vue-charts 所渲染的图标在f11进入全屏,然后退出全屏的时候会出现高度溢出的问题,这个问题排查后发现是因为进入全屏后,图标canvas 的高度会变高,退出的时候没有resize回去。解决方案:在退出全屏的时候手动调一次。f11 也会触发resize事件。监听这个事件处理就可以。

·6· 轮播表可以使用 Vue3SeamlessScroll

·7· echarts 使用地图步骤方法

css 复制代码
 step1:首选准备好地图容器和地图geo json数据
<div id="china-map-chart" ref="mapRef"></div>
geoJsonUrl='/xxx/xxx/area.json'

step:2 获得地图数据

const getMap = async (area) => {
  const { data } = await axios.get(
    `${geoJsonUrl}`
  );
  return data;
};

step3: 初始化地图

Chart = echarts.init(mapRef.value);
window.addEventListener("resize", resize, false);


const initOption = async () => {
  const Geo = await getMap(props.area); //获得地图数据
  echarts.registerMap("bd", Geo); //注册
  const mapDate = Geo.features.map(({ properties }) => {
    const Rowobj = props.data.find(
      (c) => c.name === properties.name || properties.name.includes(c.name)
    );
    const { name, centroid } = properties;

    return {
      name,
      value: centroid,
      datas: parseInt(Math.random() * 1000),
      img: `image://${new URL("@/assets/images/screen/location.svg", import.meta.url).href}`,
      current: {},
      customData: {
        ...Rowobj
      }
    };
  });
  const aspectScale = 0.75;

  const option = {
    geo: [
      {
        map: "bd",
        aspectScale,
        zoom: 0.98,
        layoutCenter: ["50%", "50%"],
        layoutSize: "100%",
        silent: true,
        roam: false,
        zlevel: 1,

        itemStyle: {
          areaColor: {
            image: mapDomImg, //配置图片
            repeat: "repeat" //可选值repeat、no-repeat、repeat-x、r
          },
          borderColor: "#3282ca",
          borderWidth: 2
        },
        emphasis: {
          itemStyle: {
            areaColor: "#2AB8FF",
            borderWidth: 1,
            color: "green"
          },
          label: {
            show: false
          }
        }
      },
      {
        map: "bd",
        aspectScale,
        zoom: 0.98,
        layoutCenter: ["50%", "50%"],
        layoutSize: "100%",
        silent: true,
        roam: false,
        zlevel: -1,
        itemStyle: {
          borderColor: "#c2e6ff",
          borderWidth: 10
        },
        tooltip: {
          show: false
        }
      },
      {
        map: "bd",
        aspectScale,
        zoom: 0.98,
        layoutCenter: ["50%", "52%"],
        layoutSize: "100%",
        silent: true,
        roam: false,
        zlevel: -2,
        itemStyle: {
          borderColor: "#0b76c1",
          borderWidth: 1,
          areaColor: "#0b619e"
        },
        tooltip: {
          show: false
        }
      },
      {
        map: "bd",
        aspectScale,
        zoom: 0.98,
        layoutCenter: ["50%", "54%"],
        layoutSize: "100%",
        silent: true,
        roam: false,
        zlevel: -3,
        itemStyle: {
          borderColor: "#095a94",
          borderWidth: 1,
          areaColor: "#084875"
        },
        tooltip: {
          show: false
        }
      },
      {
        map: "bd",
        aspectScale,
        zoom: 0.98,
        layoutCenter: ["50%", "55.4%"],
        layoutSize: "100%",
        silent: true,
        roam: false,
        zlevel: -4,
        itemStyle: {
          borderColor: "#1aa0ff",
          borderWidth: 1,
          areaColor: "#052f4c"
        },
        tooltip: {
          show: false
        }
      }
    ],
    tooltip: {
      // show: false,
      show: true,
      className: "situation-screen-tooltip-wrapper",
      formatter: (params) => {
        const tooltipList = get(params, "data.customData.tooltipList", []);

        const bg = `background-image: url(${TooltipBg});`;
        // todo  传一个list进来展示字段
        let str = "";

        tooltipList.forEach((item) => {
          str += ` <div class="tooltip-item flex flex-sp-bt">
                    <div class="tooltip-label">${item.label}</div>
                    <div class="tooltip-value">${item.value}</div>
                   </div>`;
        });

        return `<div class='tooltip-content' style='${bg}'>
                   <div class="title">${params.name}</div>
                  ${str}
                </div>`;
      }
    },
    series: [
      {
        type: "map",
        coordinateSystem: "geo",
        aspectScale,
        label: {
          show: false,
          color: "#fff"
        },
        itemStyle: {
          borderColor: "transparent",
          areaColor: "transparent"
        },
        emphasis: {
          itemStyle: {
            areaColor: "rgba(0,0,0, .1)"
          },
          label: {
            show: false,
            color: "#fff"
          }
        },
        zlevel: 2,
        scaleLimit: {
          min: 0.5,
          max: 1.5
        },
        zoom: 1.1,
        map: "bd",
        roam: "false",
        select: {
          disabled: true
        },
        silent: false,
        data: mapDate
      },
      // 水波
      {
        tooltip: {
          show: false
        },
        type: "effectScatter",
        coordinateSystem: "geo",
        rippleEffect: {
          scale: 5,
          brushType: "stroke"
        },
        showEffectOn: "render",
        itemStyle: {
          shadowColor: "#0ff",
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          color: function (params) {
            return scatterColors[params.data.status];
          }
        },
        label: {
          color: "#fff"
        },
        symbol: "circle",
        symbolSize: [10, 5],
        data: mapDate,
        zlevel: 1
      },
      // 标志
      {
        type: "scatter",
        coordinateSystem: "geo",
        roam: true,
        label: {
          show: true,
          color: "#fff",
          formatter: (params) => {
            const showCount = get(params, "data.customData.value", 0);
            return `{blue|${params.name} } \n {value|${showCount}}`;
          },
          offset: [0, -22],
          rich: {
            2: {
              borderRadius: 2,
              borderWidth: 1,
              shadowOffsetX: 4,
              shadowOffsetY: 4,
              shadowBlur: 4,
              padding: [6, 12],
              background: "rgba(0, 0, 0, 0.01)",
              color: "#FF9701",
              borderColor: "#FF9701",
              shadowColor: "rgba(250, 196, 57, 0.40)"
            },
            1: {
              borderRadius: 2,
              borderWidth: 1,
              shadowOffsetX: 4,
              shadowOffsetY: 4,
              shadowBlur: 4,
              padding: [6, 12],
              background: "rgba(0, 0, 0, 0.01)",
              color: "#00FFC2",
              borderColor: "#00FFC2",
              shadowColor: "rgba(17, 235, 156, 0.56)"
            },
            4: {
              borderRadius: 2,
              borderWidth: 1,
              shadowOffsetX: 4,
              shadowOffsetY: 4,
              shadowBlur: 4,
              padding: [6, 12],
              background: "rgba(0, 0, 0, 0.01)",
              color: "#f5222d",
              borderColor: "#f5222d",
              shadowColor: "rgba(255, 255, 255, 0.31)"
            },
            blue: {
              color: "#afd7e3",
              fontSize: 14,
              fontWeight: 600
            },
            value: {
              color: "#fff",
              fontSize: 0,
              fontWeight: 400,
              padding: [6, 12]
            }
          }
        },
        symbol: "image://",
        // symbol: function (value, params) {
        //   return "image://" + icons[params.data.status];
        // },
        // symbolSize: [20, 20],
        // symbolOffset: [0, -20],
        zlevel: 9998,
        data: mapDate
      }
    ]
  };
  Chart.setOption(option, true);
  Chart.on("click", function (params) {
    // 回调函数,处理点击事件
    if (params.componentType === "series") {
      // 判断点击的是否是系列数据(地图区域)
      console.log("点击了地图区域:", params);
      // 在这里可以添加其他处理逻辑,如显示详细信息、跳转页面等
    }
  });
};

 
相关推荐
我是日安2 小时前
从零到一打造 Vue3 响应式系统 Day 8 - Effect:深入剖析嵌套 effect
前端·vue.js
小lan猫2 小时前
React学习笔记(一)
前端·react.js
晨米酱2 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
拜无忧2 小时前
【教程】Nuxt v4 入门指南与实践 (vue前端角度开发)
前端·nuxt.js
云枫晖2 小时前
手写Promise-什么是Promise
前端·javascript
拜无忧2 小时前
html,svg,花海扩散效果
前端·css·svg
DevUI团队2 小时前
🚀 MateChat V1.8.0 震撼发布!对话卡片可视化升级,对话体验全面进化~
前端·vue.js·人工智能
RoyLin2 小时前
TypeScript设计模式:责任链模式
前端·后端·typescript
一枚前端小能手2 小时前
📋 前端复制那点事 - 5个实用技巧让你的复制功能更完美
前端·javascript