在vue中点击右键出现自定义操作菜单

在vue中点击右键出现自定义操作菜单

在网页中我们也希望可以像桌面软件一样,点击右键后出现操作菜单,对选中的数据项进行相应的操作,接下来就为大家介绍使用原生vue进行右键出现菜单的方法,并贴上详细介绍的代码

最终效果

在这里插入图片描述

代码

这个是我们要进行点击的时候点击的目标组件

  • @contextmenu.prevent.stop 为阻止浏览器的右键点击菜单事件
  • 我们的菜单相当于是独立于原本所在的内容的,所以原本的内容使用一个 div 包起来,menu 另外包起来
  • 同时我们要为其出现的地方进行调整 menuTop,menuLeft,在展示 menu 的时候我们将 event 的页面位置属性 e.pageX 和 e.pageX 拿来赋值
  • isShowMenu: 来控制菜单的显示
  • hiddenMenu: 是为了方便我们的菜单子组件在进行对应的操作以后要使菜单消失
  • :conversation: 就是我们要执行操作的数据项了
  • 我们需要在页面创建的时候增加 clickmousedonw 的监听,这样就可以在我们点击别的地方的时候将菜单隐藏
<template>
    <div class = "conversation-info" @contextmenu.prevent.stop="showMenu">
        <div class="wrapper" >
            <el-badge
                :value="conversation.unreadNum"
                :hidden="conversation.unreadNum === 0">
                <div class="conversation-avatar">
                <el-avatar shape="square" size="large" :src="conversation.photo"></el-avatar>
                </div>
            </el-badge>
            <div class="conversation-detail">
                <div class="top-item">
                <div class="ellipsis">
                    <span>{{ conversation.name }}</span>
                </div>
                <div>
                    <span style="font-size:12px;">{{ conversation.createTime | formatDateToZH }}</span>
                </div>
                </div>
                <div class="bottom-item ellipsis">
                <span class="conversation-message">
                    {{ conversation.message }}
                </span>
                </div>
            </div>
        </div>
        <div class="menu" v-if="isShowMenu" :style="{'left': menuLeft + 'px', 'top': menuTop + 'px'}">
          <home-menu
            :conversation="conversation"
            @hiddenMenu="hiddenMenu"
          />
        </div>
    </div>
</template>
<script>
import homeMenu from '@/components/menu/HomeMenu'
import {formatDateToZH} from '@/utils'
export default {
  name: 'ConversationItem',
  components: { homeMenu },
  props: ['conversation'],
  data () {
    return {
      isShowMenu: false,
      menuTop: 0,
      menuLeft: 0
    }
  },
  filters: {
    formatDateToZH (val) {
      return formatDateToZH(val)
    }
  },
  created () {
    document.addEventListener('click', () => {
      this.isShowMenu = false
    })
    document.addEventListener('mousedown', (e) => {
      const {button} = e
      if (button === 2) {
        this.isShowMenu = false
      }
    })
  },
  methods: {
    showMenu (e) {
      this.isShowMenu = true
      this.menuLeft = e.pageX
      this.menuTop = e.pageY
    },
    hiddenMenu () {
      this.isShowMenu = false
    }
  }
}
</script>
<style>
.conversation-info {
  height: 60px;
  padding: 0 10px 0;
  background-color: #e6e6e6;
}
.conversation-info .active {
  height: 60px;
  padding: 0 10px 0;
  background-color: #cfcfcf;
}
.conversation-info:hover {
  height: 60px;
  padding: 0 10px 0;
  background-color: #cfcfcf;
}
.conversation-info .menu {
    position: fixed;
    z-index: 1004;
    background-color: #fff;
    border-radius: 5px;
}
.conversation-info .wrapper {
  display: flex;
  height: 60px;
  padding: 0 5px;
  align-items: center;
  border-radius: 10px;
  overflow: hidden;
}
.el-badge {
  top: 4px;
  overflow: visible;
}
.conversation-avatar {
  width: 40px;
  height: 40px;
}
.conversation-detail {
  margin-left: 10px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.top-item {
  height: 20px;
  width: 260px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
.bottom-item {
  height: 14px;
  margin-top: 6px;
  font-size: 12px;
  color:#968b8b;
  width: 200px;
}
.conversation-message {
  float: left;
}
.ellipsis{
  display: inline-block;
  overflow: hidden;
  text-overflow:ellipsis;
  white-space: nowrap;
}
</style>

这个就是我们真正的菜单组件了

  • props: ['conversation']: 方便我们接受数据,以便在点击对应菜单后进行相应的操作
  • this.$emit('hiddenMenu'): 表示我们在执行完成该菜单操作后向父组件进行通讯,让其关闭菜单
<template>
  <div class="conversation-item-menu box-shadow1">
    <span class="menu-item operation-text" @click.stop="remove">关闭会话</span>
    <span class="menu-item operation-text" @click.stop="stick">置顶</span>
    <span class="menu-item operation-text" @click.stop="notShow">不显示会话</span>
    <el-popover
      placement="top"
      width="160"
      v-model="showDelPop">
      <p>删除会话后聊天记录等信息也会被删除,是否删除?</p>
      <div style="text-align: right; margin: 0">
        <el-button size="mini" type="text" @click="showDelPop = false">取消</el-button>
        <el-button type="primary" size="mini" @click.stop="deleteConversation">确定</el-button>
      </div>
      <span slot="reference" class="menu-item operation-text" @click.stop="()=>{}">删除会话</span>
    </el-popover>
  </div>
</template>

<script>
export default {
  name: 'HomeMenu',
  props: ['conversation'],
  data () {
    return {
      showDelPop: false,
      friendInfo: {}
    }
  },
  computed: {
    userInfo () {
      return this.$store.state.user.userInfo
    }
  },
  methods: {
    remove () {
      console.log('删除:', this.conversation.name)
      this.$emit('hiddenMenu')
    },
    stick () {
      console.log('置顶:', this.conversation.name)
      this.$emit('hiddenMenu')
    },
    notShow () {
      console.log('不显示会话:', this.conversation.name)
      this.$emit('hiddenMenu')
    },
    deleteConversation () {
      console.log('删除会话:', this.conversation.name)
      this.$emit('hiddenMenu') // 关闭菜单
    }
  }
}
</script>

<style>
.conversation-item-menu {
  padding: 5px;
}
.box-shadow1 {
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
}
.menu-item {
    display: block;
    margin-top: 5px;
}
.operation-text {
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 3px;
  color: #7e7e7e;
  transition: all .5s ease-in;
}
.operation-text:hover {
  background-color: #E9EAEC;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值