九、Vben之可拖拽穿梭框和水印背景如何添加

        近期在开发的过程中遇到了两个难题,一个是目前的穿梭框不支持产品的要求,不能够上下拖拽,二是vben没有水印的api,需要我们自己来开发。

一、可拖拽穿梭框

        做成功的效果如下:

思路:

  1. 将table放入transfer的slot里进行使用。

     2、将table的拖拽事件写出来,让其中的值赋值正确

     3、因为左边不能拖动,右边可以拖动,判断是否为right来绑定是否拖拽事件

代码展示

html代码

<!-- 新增编辑弹窗 -->
<AddEditModel
  :addFormSchema="addFormSchema"
  :title="'薪酬方案'"
  @register="registerModal1"
  @success="handleSuccess1"
  @cancel="handleCancel1"
>
  <template #itemIds="{ model, field }">
    <Transfer
      ref="transferRef"
      :titles="['待选薪酬项目', '已选薪酬项目']"
      v-model:target-keys="model[field]"
      :data-source="mockData"
      show-search
      :list-style="{
        width: '210px',
        height: '300px',
      }"
      :render="(item) => `${item.title}`"
    >
      <template #notFoundContent>
        <span>没数据</span>
      </template>
      <template
        #children="{ direction, filteredItems, selectedKeys, onItemSelectAll, onItemSelect }"
      >
        <Table
          :row-selection="
            getRowSelection({
              selectedKeys,
              onItemSelectAll,
              onItemSelect,
            })
          "
          :columns="TransferColumns"
          :data-source="filteredItems"
          :pagination="false"
          :scroll="{
            y: 160,
          }"
          height="400"
          size="small"
          :customRow="direction === 'right' ? customRow.bind(list, filteredItems) : undefined"
        />
      </template>
    </Transfer>
  </template>
</AddEditModel>

Js代码

// 拖动排序
function customRow(list, record) {
  return {
    props: {
      draggable: 'true',
    },
    style: {
      cursor: 'move',
    },
    // 鼠标移入
    onMouseenter: (event) => {
      // 兼容IE
      var ev = event || window.event;
      ev.target.draggable = true;
    },
    // 开始拖拽
    onDragstart: (event) => {
      var ev = event || window.event; // 兼容IE
      ev.stopPropagation(); // 阻止冒泡
      fistIndex.value = list.findIndex(function (event) {
        return event.key === record.key;
      });
    },
    // 拖动元素经过的元素
    onDragover: (event) => {
      var ev = event || window.event;
      ev.preventDefault(); // 阻止默认行为
    },
    // 鼠标松开
    onDrop: (event) => {
      var ev = event || window.event;
      ev.stopPropagation(); // 阻止冒泡
      let tagIndex = list.findIndex(function (event) {
        return event.key === record.key;
      });
      let temp = list[fistIndex.value];
      set(list, fistIndex.value, list[tagIndex]);
      set(list, tagIndex, temp);
      sortList.value = list;
    },
  };
}
const getRowSelection = ({
  disabled,
  selectedKeys,
  onItemSelectAll,
  onItemSelect,
}: Record<string, any>) => {
  return {
    getCheckboxProps: (item: Record<string, string | boolean>) => ({
      disabled: disabled || item.disabled,
    }),
    onSelectAll(selected: boolean, selectedRows: Record<string, string | boolean>[]) {
      const treeSelectedKeys = selectedRows
        .filter((item) => !item.disabled)
        .map(({ key }) => key);
      onItemSelectAll(treeSelectedKeys, selected);
    },
    onSelect({ key }: Record<string, string>, selected: boolean) {
      onItemSelect(key, selected);
    },
    selectedRowKeys: selectedKeys,
  };
};

二、水印问题

        客户要求在table背后加上公司的水印,vben框架没有这个的api,我们自己开发完成。效果图如下:

需求:给整个页面添加背景水印。

  思路:

    1、使用 canvas 特性生成 base64 格式的图片文件,设置其字体大小,颜色等。

    2、将其设置为背景图片,从而实现页面或组件水印效果

    3、监听新旧父元素宽高,让水印填充满

使用:设置水印文案,颜色,字体大小即可

 <div v-waterMarker="{text:'版权所有',textColor:'rgba(180, 180, 180, 0.4)'}"></div>

废话不多说,直接上代码:

import type { Directive, DirectiveBinding, App } from 'vue';
function createBase64(
  str: string,
  textSize: number,
  textColor: string,
  textXGap: number,
  textYGap: number
) {
  const can = document.createElement('canvas')
  const width = textXGap || 300
  const height = textYGap || width / 3
  Object.assign(can, { width, height })
  const cans = can.getContext('2d')
  if (cans) {
    cans.rotate((-20 * Math.PI) / 120)
    cans.font = textSize + 'px Microsoft JhengHei' || '16px Microsoft JhengHei'
    cans.fillStyle = textColor || 'rgba(0, 0, 0, 0.15)'
    cans.textAlign = 'left'
    cans.textBaseline = 'middle'
    cans.fillText(str, width / 10, height)
  }
  return can.toDataURL('image/png')
}
const addWaterMarker = (
  str: string,
  parentNode: any,
  textSize: number,
  textColor: string,
  textXGap: number,
  textYGap: number
) => {
  const el = parentNode
  const waterMarkerlist = document.getElementsByClassName('waterMarker-box')
  if (waterMarkerlist.length) {
    for (let i = 0; i < waterMarkerlist.length; i++) {
      el.removeChild(waterMarkerlist[i])
    }
  }
  el.style.position = 'relative'
  const { clientHeight: height, clientWidth: width } = el
  const div = document.createElement('div')
  div.style.pointerEvents = 'none'
  div.className = 'waterMarker-box'
  div.style.top = '0px'
  div.style.left = '0px'
  div.style.position = 'absolute'
  div.style.height = height + 'px'
  div.style.width = width + 'px'
  div.style.zIndex = '100000'
  div.style.background = `url(${createBase64(
    str,
    textSize,
    textColor,
    textXGap,
    textYGap
  )}) left top repeat`
  el.appendChild(div)
}
const waterMarker = {
  mounted(el: DirectiveBinding, binding: DirectiveBinding) {
    let width = '',
      height = '';
    function isReize() {
      const style = document.defaultView.getComputedStyle(el);
      if (width !== style.width || height !== style.height) {
        addWaterMarker(
          binding.value.text,
          el,
          binding.value.textSize,
          binding.value.textColor,
          binding.value.textXGap,
          binding.value.textYGap
        )
      }
      width = style.width;
      height = style.height;
    }
    el.__vueSetInterval__ = setInterval(isReize, 300);
  },
};
export function setupWaterMarkerDirective(app: App) {
  app.directive('waterMarker', waterMarker);
}
export default waterMarker;

        以上就是拖拽穿梭框和背景水印的核心内容,如果使用的是vben框架的话,大家会更容易理解,有什么不同的问题,可以留言一起讨论哦。

猜你喜欢

转载自blog.csdn.net/qq_43185384/article/details/129193662
今日推荐