vue3+elementPlus:el-tree复制粘贴数据功能,并且有弹窗组件

在tree控件里添加@contextmenu属性表示右键点击事件。

因右键自定义菜单事件需要获取当前点击的位置,所以此处绑定动态样式来控制菜单实时跟踪鼠标右键点击位置。

//html
<div class="box-list">
  <el-tree ref="treeRef" node-key="id" :props="{ label: 'name', isLeaf: 'leaf' }" :load="loadNode" lazy
    highlight-current :expand-on-click-node="true" @node-click="handleNodeClick" :filter-node-method="filterNode">
    <template #default="{ node, data }">
    <!-- @contextmenu表示右键点击事件 -->
      <span class="custom-tree-node" @contextmenu.prevent.native="openMenu($event, data)">
        <svg class="icon svg-icon" aria-hidden="false">
          <use :xlink:href="`#` + data.icon"></use>
        </svg>
        <span>
          {{ data.name }}
        </span>
      </span>
    </template>
  </el-tree>
</div>

<!-- 因右键自定义菜单事件需要获取当前点击的位置,所以此处绑定动态样式来控制菜单实时跟踪鼠标右键点击位置 -->
  <ul v-show="visible" :style="{ left: leftMenu + 'px', top: topMenu + 'px' }" class="contextmenu">
    <li @click="onCopy(datalist.copyData)" v-if="datalist.copyData.nodeType != 1">复制</li>
    <li @click="POPshow = true; onPaste(datalist.copyData)">粘贴</li>
  </ul>

  <div v-show="POPshow">
    <div :style="{ left: leftMenu + 'px', top: topMenu + 'px' }" class="contextmenu">
      <p>您复制的是{{ CopyName }},</p>
      <p>确定要粘贴到{{ PasteName }}?</p>
      <el-button style="width:48px;height:24px;" @click="POPshow = false;">取消</el-button>
      <el-button type="primary" style="width:48px;height:24px;" @click="onDefine">确定</el-button>
    </div>
  </div>
  
//js
// 右键菜单
const visible = ref(false)
const topMenu = ref(0)
const leftMenu = ref(0)
const openMenu = (e, val) => {
  datalist.copyData = val

  let x = e.pageX; //这个应该是相对于整个浏览器页面的x坐标,左上角为坐标原点(0,0)
  let y = e.pageY; //这个应该是相对于整个浏览器页面的y坐标,左上角为坐标原点(0,0)
  topMenu.value = y;
  leftMenu.value = x;
  visible.value = true; //显示菜单

}
//关闭菜单
const closeMenu = () => {
  visible.value = false; //关闭菜单
}

//监听菜单组件
watch(() => visible.value, (newValue, oldValue) => {
  //   监听属性对象,newValue为新的值,也就是改变后的值
  if (newValue) {
    //菜单显示的时候
    // document.body.addEventListener,document.body.removeEventListener它们都接受3个参数
    // ("事件名" , "事件处理函数" , "布尔值");
    // 在body上添加事件处理程序
    document.body.addEventListener("click", closeMenu);
  } else {
    //菜单隐藏的时候
    // 移除body上添加的事件处理程序
    document.body.removeEventListener("click", closeMenu);
  }
})

// 复制 按钮
const CopyID = ref()
const CopyName = ref()
const onCopy = async (val) => {
  // console.log(e,'e复制事件');
  // console.log(val, 'val复制事件');
  datalist.copyData = val
  CopyID.value = val.id
  CopyName.value = val.name
}
// 粘贴 按钮
const PasteName = ref()
const onPaste = async (val) => {
  PasteName.value = val.name
}
// 复制粘贴 确定按钮
const PasteID = ref()
const POPshow = ref(false)
const onDefine = async () => {
  PasteID.value = datalist.copyData.id
  await getCopyPaste(CopyID.value, PasteID.value)
  POPshow.value = false
  TreeNode.value.loaded = false
  // 主动调用展开节点方法,重新查询该节点下的所有子节点
  TreeNode.value.expand()
  handleModel(id.value)
}
// 调用复制 粘贴 接口
const getCopyPaste = async (copyNodeId, pasteNodeId) => {
  let res = await CopyTreeList({ copyNodeId: copyNodeId, pasteNodeId: pasteNodeId })
  if (res.status != 200) {
    ElNotification({
      title: '提示',
      message: res.data.message,
      type: 'error',
    })
  }
}


//css
// 右键菜单组件
.contextmenu {
  margin: 0;
  background: #fff;
  z-index: 3000;
  position: fixed; //关键样式设置固定定位
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
}

.contextmenu li {
  margin: 0;
  padding: 7px 16px;
  cursor: pointer;
}

.contextmenu li:hover {
  background: #eee;
}

上一篇文章,

vue2踩坑之项目:生成二维码使用vue-print-nb打印二维码_意初的博客-CSDN博客vue2踩坑之项目:生成二维码使用vue-print-nb打印二维码,import print from 'vue3-print-nb' directives: { print } //自定义指令中注册。vue3安装 npm install vue3-print-nb --save。vue2安装 npm install vue-print-nb --save。directives: { print} //自定义指令中注册。//vue2 引入方式 全局 main.js。https://blog.csdn.net/weixin_43928112/article/details/132725143

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值