Skip to main content Skip to footer

Adding Vue Menu Items Declaratively

Before now, the only way to add items to a wj-menu component was to bind it to an array of menu items data. To customize the look of the items, you had to use a formatItem event and generate their content in JS code. But when you create UI in Vue templates, this approach (where one part of a menu must be defined in a template and the other one should be created in a code-behind), may look inconvenient. You may prefer to define both the menu and its items right here, in the template - in one single place.

This is now possible by means of the new wj-menu-item component from the @grapecity/wijmo.vue2.input module.

Instead of defining items in an array, you can now use wj-menu-item components nested to their wj-menu. Every wj-menu-item defines a separate menu item, with content of an arbitrary complexity in it, which may include other components with bindings.

In addition, a wj-menu-separator component can be used to insert separators between menu items. For example, the following piece of Vue markup from this sample defines File menu items with rich content and a separator before the Exit item:

<wj-menu :header="'File'" :itemClicked="menuItemClicked">
    <wj-menu-item>
        <span class="glyphicon glyphicon-asterisk"></span>&nbsp;&nbsp;
        <b>New</b>
        <br>
        <small><i>create a new file</i></small>
    </wj-menu-item>
    <wj-menu-item>
        <span class="glyphicon glyphicon-folder-open"></span>&nbsp;&nbsp;
        <b>Open</b>
        <br>
        <small><i>open an existing file or folder</i></small>
    </wj-menu-item>
    <wj-menu-item>
        <span class="glyphicon glyphicon-floppy-disk"></span>&nbsp;&nbsp;
        <b>Save</b>
        <br>
        <small><i>save the current file</i></small>
    </wj-menu-item>
    <wj-menu-separator></wj-menu-separator>
    <wj-menu-item>
        <span class="glyphicon glyphicon-remove"></span>&nbsp;&nbsp;
        <b>Exit</b>
        <br>
        <small><i>exit the application</i></small>
    </wj-menu-item>
</wj-menu>

You can also generate multiple wj-menu-item(s) dynamically from an array of items describing their data, with the help of the Vue v-for directive.

For example, the markup snippet below, taken from this sample, generates menu items from the palettes array:

<wj-menu
    :header="'Palette'"
    :value="selectedPalette"
    :itemClicked="selectedPaletteChanged">
    <wj-menu-item :value="palette.name" v-for="palette in palettes">
        <div>
            {{palette.name}}
            <span style='float: right'>
                <div
                    v-for="color in palette.colors"
                    v-bind:style="{
                        backgroundColor: color,
                        display:'inline',
                        padding:'2px',
                        height:'10px',
                        width:'3px'                       
                    }">
                </div>
            </span>
        </div>
    </wj-menu-item>
</wj-menu>

Note that the wj-menu component here is not bound to a data array using its itemsSource property. Instead, it generates child wj-menu-item components from the data array.

Commands

You can now declaratively define menu items bound to commands with parameters. The wj-menu-item component exposes cmd and cmdParam properties out of its interface, which can be bound to a command and its parameter respectively.

The markup snippet below, taken from this sample, demonstrates the use of these properties to define menu items that increment or decrement a value. Each item represents a different increment value specified as the command parameter:

<wj-menu id="changeTax" :header="'Tax Commands'">
    <wj-menu-item :cmd="command" :cmdParam="0.50">Increment by 50%</wj-menu-item>
    <wj-menu-item :cmd="command" :cmdParam="0.25">Increment by 25%</wj-menu-item>
    <wj-menu-item :cmd="command" :cmdParam="0.05">Increment by 5%</wj-menu-item>
    <wj-menu-separator></wj-menu-separator>
    <wj-menu-item :cmd="command" :cmdParam="-0.05">Decrement by 5%</wj-menu-item>
    <wj-menu-item :cmd="command" :cmdParam="-0.25">Decrement by 25%</wj-menu-item>
    <wj-menu-item :cmd="command" :cmdParam="-0.50">Decrement by 50%</wj-menu-item>
</wj-menu>

Value Pickers

The wj-menu component can now be used as a value picker. The wj-menu-item component has the value property containing a value associated with the item. And the wj-menu itself has the value property, whose value is displayed next to the menu header. This property can be bound to the parent component state, and the itemClicked event can be used to update the state with the value associated with the selected menu item.

This is demonstrated in this example showing the menu that can be used to choose a browser name:

Template:
<wj-menu
        :header="'Run'"
        :value="browser"
        :itemClicked="splitButtonItemClicked">
    <wj-menu-item :value="'IE'">Internet Explorer</wj-menu-item>
    <wj-menu-item :value="'Chrome'">Chrome</wj-menu-item>
    <wj-menu-item :value="'FF'">FireFox</wj-menu-item>
    <wj-menu-item :value="'Safari'">Safari</wj-menu-item>
    <wj-menu-item :value="'Opera'">Opera</wj-menu-item>
</wj-menu>


JavaScript:
splitButtonItemClicked: function(menu) {
    this.browser = menu.selectedItem.value;
}

Conclusion

With the introduction of wj-menu-item and wj-menu-separator components, defining menus in your Vue application became way more convenient. The entire menu with all its items can be defined right in the component template. Items may contain rich content, including HTML elements, or another components with bindings.

Alex Ivanenko

Program Manager
comments powered by Disqus