【实践功能记录6】表格列悬浮展示tooltip信息

需求描述:

鼠标悬浮在表格的IP字段上时,使用tooltip展示IP信息,如图:

1.封装根据IP展示信息的组件

请求接口获取IP信息,注意请求接口时防抖

<!-- 根据IP展示资产信息 -->
<template>
  <div>
    <el-tooltip placement="left" trigger="hover" :show-after="500">
      <template #content>
        <div v-if="state.ipAssetLoading">loading</div>
        <div v-else>
          <!-- IP信息 -->
          <div>
            <div class="font-bold">{{ t('alertQuery.ipInfo') }}:</div>
            <div>{{ t('alertQuery.ipInfo_ip') }}: {{ state.showIp }}</div>
            <div>{{ t('alertQuery.ipInfo_address') }}: {{ state.showAssetInfo.ipAddressInfo }}</div>
          </div>
          <!-- 资产信息 -->
          <template v-if="!_.isEmpty(state.showAssetInfo.ipAssetInfo)">
            <el-divider></el-divider>
            <div class="font-bold">{{ t('alertQuery.assetInfo') }}:</div>
            <div v-for="item of state.showAssetInfo.ipAssetInfo" :key="item.key">
              <div>{{ item.label }}: {{ item.value }}</div>
            </div>
          </template>
        </div>
      </template>
      <el-link type="primary" @mouseenter="initIpAsset(state.ipValue)" :underline="false">
        {{ state.ipValue }}
      </el-link>
    </el-tooltip>
  </div>
</template>

<script setup lang="ts">
import _ from '@lodash';
import { initIpInfoLink } from '@/utils/util';
import { getIpInfo } from '@/api/common';
import type { AssetInfo } from '@/api/common';

const { t } = useI18n();
const state = reactive({
  ipAssetLoading: false,
  showAssetInfo: {} as AssetInfo,
  ipValue: '',
  showIp: '',
});
const props = defineProps<{ rowValue: string }>();

watch(
  () => props.rowValue,
  () => {
    state.ipValue = props.rowValue;
  },
  { immediate: true },
);

// 获取IP地址及资产信息
const searchInfoDebounce = _.debounce((_ip) => getIpAsset(_ip), 500);
// 获取IP
async function initIpAsset(ip: string) {
  state.showIp = await initIpInfoLink(ip);
  searchInfoDebounce(state.showIp);
}
async function getIpAsset(ip: string) {
  try {
    state.ipAssetLoading = true;
    const res = await getIpInfo(ip);
    if (res?.code) throw new Error(res?.message);
    state.showAssetInfo.ipAddressInfo = res?.data?.ipAddressInfo ?? '';
    state.showAssetInfo.ipAssetInfo = res?.data?.ipAssetInfo ?? [];
  } catch (error) {
    if (error === 'cancel' || error?.code === RESPONSE_CODE.CANCEL) return;
    console.log(`[log] - getIpInfo - error:`, error);
  } finally {
    state.ipAssetLoading = false;
  }
}
</script>

获取IP信息的方法

// 获取IP
export async function initIpInfoLink(ip: string) {
  if (!ip) return '';
  ip = _.escape(ip);
  let _ip = ip;
  // 兼容特殊的这种写法 192.168.2.101(192.168.2.101)
  if (_ip.includes('(')) {
    _ip = _ip.substr(0, _ip.indexOf('('));
  }
  // IP:端口格式
  if (_ip.includes(':')) {
    _ip = _ip.substr(0, _ip.indexOf(':'));
  }
  return _ip;
}
2.请求接口的文件

为了防止接口重复请求时请求被中断,在请求接口的时候加上时间Date.now()

// 通用接口
import type { ResDto } from '@/utils/request';

// 根据IP查询资产信息
export interface AssetInfo {
  ipAssetInfo: { label: string; value: string; key: string }[];
  ipAddressInfo: string;
}
export function getIpInfo(ip: string): ResDto<AssetInfo> {
  return SecRequest({
    method: 'POST',
    url: '/test/alert/ip?time=' + Date.now(),
    data: { ip },
  });
}
3.在表格列中调用方法

首先判断表格的字段是否符合IP格式,符合再去调用封装好的组件

<el-table-column
    v-for="col of appState.headList"
    :key="col.value"
    :label="col.label"
    :prop="col.value"
    align="center">
     <template #default="scope">
         <!--添加ip悬浮查看信息 -->
         <template v-if="isFieldIP(scope.row[col?.value])">
             <ShowIpAsset :rowValue="scope.row[col?.value] ?? ''"></ShowIpAsset>
         </template>
     </template>
</el-table-column>

// 导入组件
import ShowIpAsset from '@/components/VIpAsset/ShowIpAsset.vue';
// 判断字段内容是否符合IP格式
import { isFieldIP } from '@/utils/validate';

判断是否为IP字段

// 判断是否为IP字段
export function isFieldIP(ip: string) {
  ip = _.escape(ip);
  let _ip = ip;
  if (_ip?.includes(':')) {
    _ip = _ip.substr(0, _ip.indexOf(':'));
  }
  const reg =
    /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
  return reg.test(_ip);
}

最近更新

  1. TCP协议是安全的吗?

    2024-06-14 09:22:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-14 09:22:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-14 09:22:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-14 09:22:04       20 阅读

热门阅读

  1. 【安全函数】常用的安全函数的使用

    2024-06-14 09:22:04       6 阅读
  2. 快速入门Flutter:从零开始构建你的第一个应用

    2024-06-14 09:22:04       7 阅读
  3. C++Primer Plus编程题(第五章)

    2024-06-14 09:22:04       8 阅读
  4. Webrtc支持FFMPEG硬解码之解码实现(三)

    2024-06-14 09:22:04       11 阅读
  5. ### RabbitMQ五种工作模式:

    2024-06-14 09:22:04       10 阅读
  6. 【设计模式】结构型设计模式之 桥接模式

    2024-06-14 09:22:04       9 阅读
  7. 威胁情报多场景下的实战技术落地

    2024-06-14 09:22:04       9 阅读
  8. Hudi extraMetadata 研究总结

    2024-06-14 09:22:04       9 阅读