vue-v-contextmenu
v2.1.0
Published
AN Vue directive of contextmenu
Downloads
3
Maintainers
Readme
vue-v-contextmenu
contextmenu vue directive and component based on Vue 2.0
Introduction
为用户右键(或左键)点击目标元素触发相应的上下文菜单,基于 Vue 2.0,核心用法为 Vue 指令,另可选开箱即用的上下文菜单 Vue 组件
Install
npm install vue-v-contextmenu --save
Example
固定菜单项
<!-- 固定菜单 -->
<div v-contextmenu.trigger>
右键此方块(简单固定菜单)
</div>
<div v-contextmenu.disableHideOnClick>
<div>固定菜单项-1</div>
<div>固定菜单项-2</div>
<div>固定菜单项-3</div>
</div>
动态菜单项
根据所点击目标生成动态菜单选项
- 右键点击 Mail 项
- 右键点击 Github 项
- 右键点击 NPM 项
<template>
<!-- 动态菜单,采用组件 -->
<div
v-contextmenu:FOO.trigger="item.menu"
v-for="(item, index) in list"
:key="index"
>
右键此方块(动态菜单)- {{item.trigger}}
</div>
<DynamicContextMenu />
</template>
<script>
import DynamicContextMenu from './DynamicContextMenu'
export default {
components: { DynamicContextMenu },
data() {
return {
list: [
{
trigger: 'Mail',
menu: ['Hello', '[email protected]', ':)']
},
{
trigger: 'Github',
menu: ['World', 'i58000 @ github', ':>']
},
{
trigger: 'NPM',
menu: ['Welcome', 'anjs @ npm', ':]']
}
]
}
}
}
</script>
<!-- DynamicContextMenu.vue -->
<template>
<div v-contextmenu:FOO.menu="setData" @click="$el.hide()">
<div v-for="(item, index) in data" :key="index" class="item">{{item}}</div>
</div>
</template>
<script>
export default {
data() {
return {
data: null
}
},
methods: {
setData(data) {
this.data = data
}
}
}
</script>
左键点击
除了右键触发菜单,亦支持左键点击弹出菜单,同样支持固定/动态菜单
<!-- 左键点击 -->
<div v-contextmenu:bar.trigger.click>
左键点击此方块
</div>
<div v-contextmenu:bar.click>
<div>固定菜单项-1</div>
</div>
全局引用
默认同时引入指令和内置菜单组件:
import VContextmenu from 'vue-v-contextmenu'
Vue.use(VContextmenu)
若无需内置组件,以以下方式引用:
Vue.use(VContextmenu, { component: false })
默认内置组件名为 Contextmenu
,可自定义组件名:
Vue.use(VContextmenu, { component: 'AnohterContextmenu' })
组件内按需引用
import VContextmenu from 'vue-v-contextmenu'
import { Contextmenu } from 'vue-v-contextmenu'
export default {
directives: {
contextmenu: VContextmenu
},
components:{
Contextmenu
},
...
}
Document
指令类型
指令可分为两种类型:触发器(trigger) 和 菜单(menu)
触发器指令:携带修饰符
.trigger
指令作用于触发器的元素上菜单指令:未携带修饰符
.trigger
可作用于 DOM 元素或自定义 Vue 组件上
<!-- 基本用法 -->
<div v-contextmenu.trigger.click="data">点我弹出菜单</div>
<div v-contextmenu="setData">我是菜单本体</>
动态菜单:指令参数
指令参数值主要是针对动态菜单,只使用固定菜单的话可以忽略本节。
两种类型的指令所传递的参数有所区别:
触发器:传递数据对象
someData: any
菜单:传递动态渲染/改变菜单数据的方法
someMethod : String | Function
菜单指令的参数可传入
String
或Function
,若传入为String
,将在菜单指令所作用的元素的 Vue 组件实例中调用该方法名
简而言之:用户触发显示菜单时会执行 someMethod(someData)
以完成动态菜单的渲染。
参考示例 动态菜单
触发方式:右键 or 左键
默认为右键菜单,使用.click
指令修饰符可切换为左键单击触发菜单
<!-- 左键点击触发 -->
<div v-contextmenu.trigger.click="data" />
<div v-contextmenu="setData" />
菜单名称:多个菜单
支持多个不同的菜单,为添加菜单名称指令参数 :{name}
,触发器.trigger
和菜单指令所含的名称参数需匹配,如
<!-- 菜单 with some name -->
<div v-contextmenu:somename.trigger="data" />
<div v-contextmenu:somename="setData" />
<!-- 菜单 with other name-->
<div v-contextmenu:othername.trigger="data" />
<div v-contextmenu:othername="setData" />
菜单隐藏
菜单默认会在以下事件产生时隐藏:
- 菜单指令 DOM 被点击
click
- 菜单指令 DOM 失去焦点
blur
document
的滚动事件scroll
- 菜单指令 DOM 被点击
菜单指令提供以下相应的修饰符以取消默认隐藏事件:
- 取消菜单指令 DOM 被点击
click
:.disableHideOnClick
ordhClick
- 取消菜单指令 DOM 失去焦点
blur
:.disableHideOnBlur
ordhBlur
- 取消
document
的滚动事件scroll
:.disableHideOnScroll
ordhScroll
参考示例 固定菜单项
- 取消菜单指令 DOM 被点击
若需对菜单的隐藏做更细致的逻辑处理,可使用 DOM 元素上的
hide
方法,插件默认在菜单指令所作用的 DOM 元素上添加了hide
方法,可直接调用。<div v-contextmenu.disableHideOnClick="setData" ref="contextmenu"> <div @click="$refs.contextmenu.hide()">点我才会隐藏</div> ... </div>
参考示例 动态菜单项
Component
提供了开箱即用的 支持多级菜单 和 自定义节点模板的 Vue 组件:<Contextmenu/>
<template>
<div v-contextmenu.trigger>
右键此方块 - 内置菜单组件
</div>
<Contextmenu v-contextmenu :menu="menu" @clickMenu="onclick">
<template v-slot="{item}">
<span :style="{color: item.color}">
{{item.label}}
<template v-if="item.star"
>*</template
>
</span>
</template>
</Contextmenu>
<div v-contextmenu:DARK.trigger>
右键此方块 - 内置菜单组件 - Dark
</div>
<Contextmenu
v-contextmenu:DARK
:content="item=>item.label"
:menu="menu"
@clickMenu="onclick"
dark
></Contextmenu>
</template>
<script>
import VContextmenu from 'vue-v-contextmenu'
import { Contextmenu } from 'vue-v-contextmenu'
export default {
directives: {
contextmenu: VContextmenu
},
components: { Contextmenu },
data() {
return {
menu: [
{
label: '颜色',
children: [
{ label: '红色', color: '#f5222d' },
{ label: '蓝色', color: '#1890ff' },
{ label: '绿色', color: '#52c41a' }
]
},
{
label: '符号',
children: [
{ label: '有星星', star: true },
{ label: '没星星', star: false }
]
},
{
label: '多级菜单',
children: [
{
label: 'AAA',
children: [
{ label: 'AA', children: [{ label: 'A' }] },
{ label: 'AA', children: [{ label: 'A' }] }
]
},
{
label: 'BBB',
children: [
{ label: 'BB', children: [{ label: 'B' }] },
{ label: 'BB', children: [{ label: 'B' }] }
]
},
{
label: 'CCC',
children: [
{ label: 'CC', children: [{ label: 'C' }] },
{ label: 'CC', children: [{ label: 'C' }] }
]
}
]
}
]
}
},
methods: {
onclick(item, event) {
console.log(item, event)
// event.stopPropagation();
}
}
}
</script>
props
menu 菜单数据
type: Array
必须为数组类型的数据
数组中的元素对象的
children
属性为子菜单数组dark 深色主题
type: Boolean
default: false
content 菜单中每一项显示的内容
type: Function | String | Number
当传入一个回调函数时,参数为
menu
数据中的节点项当传入非函数类型时,作为数据节点项的索引/属性取值
events
clickMenu
点击菜单中的任一项
参数 1 为
menu
数据中的节点项参数 2 为
click
事件,调用stopPropagation()
方法阻止事件冒泡可保持菜单不隐藏
slots
default
默认插槽,参考示例 内置菜单组件
Questions
Contact me for any questions: [email protected]