2
0
mirror of https://github.com/tenrok/vue-context.git synced 2026-05-20 14:27:55 +03:00
Files
vue-context/docs/usage/advanced-usage.md
T
2020-08-31 07:38:23 -05:00

256 lines
7.3 KiB
Markdown

---
title: Advanced Usage
sort: 2
---
## Scoped Slot
To pass any data from the `contextmenu` event to your template, you can pass it as the second parameter of the `open` event
and access it within a [scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots) under the `data` property. `$event` **must be passed as the first parameter**,
otherwise the context menu will not function properly.
```html
<template>
<div>
<p @contextmenu.prevent="$refs.menu.open($event, { foo: 'bar' })">
Right click on me
</p>
<vue-context ref="menu" v-slot="{ data }">
<li>
<a @click.prevent="onClick($event.target.innerText, data)">
Option 1
</a>
</li>
<li v-if="data">
<a @click.prevent="onClick($event.target.innerText, data)">
Option 2 - {{ data.foo }}
</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
methods: {
onClick(text, data) {
alert(`You clicked "${text}"!`);
console.log(data);
// => { foo: 'bar' }
},
},
};
</script>
```
## Props
There are many props available on the context menu. Some of them include:
- `closeOnClick`
- `closeOnScroll`
- `lazy`
- `itemSelector`
- `role`
- `tag`
All props are optional. It is **not recommended** to use anything other than `ul` as a value for the tag property. If
you do choose a different tag, be sure to update the `itemSelector` prop accordingly to ensure proper keyboard navigation
can be used and the accessiblity attributes can be added to each menu item.
```html
<template>
<div>
<p @contextmenu.prevent="$refs.menu.open($event)">
Right click on me
</p>
<vue-context ref="menu"
:close-on-click="closeOnClick"
:close-on-scroll="closeOnScroll"
:lazy="lazy"
:role="role"
:tag="tag"
:item-selector="itemSelector"
>
<li>
<a class="custom-item-class">Option 1</a>
</li>
<li>
<a class="custom-item-class">Option 2</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
data() {
return {
// when set to true, the context menu will close when clicked on
closeOnClick: true,
// when set to true, the context menu will close when the window is scrolled
closeOnScroll: true,
// When false, the context menu is shown via v-show and will always be present in the DOM
lazy: false,
// The `role` attribute on the menu. Recommended to stay as `menu`
role: 'menu',
// The root html tag of the menu. Recommended to stay as `ul`
tag: 'ul',
// This is how the component is able to find each menu item. Useful if you use non-recommended markup
itemSelector: ['.custom-item-class'],
};
},
};
</script>
```
See [the api](/docs/vue-context/v6/api/api) for more information on props.
## Events
There are two events emitted by the context menu:
- `close`
- `open`
The `close` event receives no parameters and is emitted when the context menu is closed.
The `open` event is emitted when the context menu is shown and receives the following parameters:
- `event`: The event that triggered the menu opening
- `data`: Any data passed to the menu from the trigger element.
- `top`: The top (y) position of the menu.
- `left`: The left (x) position of the menu.
```html
<template>
<div>
<p @contextmenu.prevent="$refs.menu.open($event, { foo: 'bar' })">
Right click on me
</p>
<vue-context ref="menu" @close="onClose" @open="onOpen">
<li>
<a>Option 1</a>
</li>
<li>
<a>Option 2</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
methods: {
onClose() {
console.log('The context menu was closed');
},
onOpen(event, data, top, left) {
console.log('The context menu was opened');
console.log(event, data, top, left);
},
},
};
</script>
```
## Left Click
If you want to use a _left_ click to open the menu instead, just replace `@contextmenu.prevent` with `@click.prevent`
as your event listener. If you have issues with the menu closing right after you click on your target element, you
probably just need to append the `stop` modifier onto the click event. See [issue #14](https://github.com/rawilk/vue-context/issues/14) for more information.
```html
<template>
<div>
<p @click.prevent="$refs.menu.open($event)">
Right click on me
</p>
<vue-context ref="menu">
<li>
<a>Option 1</a>
</li>
<li>
<a>Option 2</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext }
};
</script>
```
## Nested Menus
Nested context menus are possible by adding the class `v-context__sub` to a child `<li>` element in the menu.
Inside the `v-context__sub` element a new container (e.g. a `<ul>` element) with the class `v-context` must be created.
The nested `v-context` container will be opened and positioned after the `v-context__sub` element is hovered or
the menu element is expanded by keyboard right click.
There is no limit on how far you can nest the menus, the only requirement is to use the proper classes on each nested menu.
```html
<template>
<div>
<p @click.prevent="$refs.menu.open($event)">
Right click on me
</p>
<vue-context ref="menu">
<li>
<a>Not nested</a>
</li>
<li class="v-context__sub">
<a>Has nested menu</a>
<ul class="v-context">
<li>
<a>Nested menu item</a>
</li>
</ul>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
};
</script>
```