Vue actual combat 8: right click menu ContextMenu, edit tree structure, admin manage background

Time:2020-10-23

Rxedior has the file management function by default, but the demand for flexibility is not great. At present, the assumption is that the folder is not allowed to be modified, only the files can be added, deleted and modified. Based on this assumption, the interface is realized as follows:

Vue actual combat 8: right click menu ContextMenu, edit tree structure, admin manage background

This function is not a general function, and the code we do is not in accordance with the standard requirements of the class library. The implementation of this editing function is a bit complicated, using a large number of JS events, and the code is not very easy to read. This feature may change a lot later, so I don’t have the motivation to make the code more elegant.
This essay will not show the code in detail, but will talk about my implementation ideas and the pit in the process of writing. If you need the source code, you can download it directly from GitHub.

1. In this project, the two trees use the same set of code, and can be distinguished by adding the editable attribute props.

<NodeTree v-model="files" :openIcon="'fas fa-folder-open'" :closeIcon="'fas fa-folder'" :editable = 'true' >
</NodeTree>

2. Add three variables to the node data. See the notes for functions:

isFolder:true , // cannot be edited. Only when the attribute is true, a new child node can be created
Leaficon: 'far FA file code', // sub node icon, which is used when building a new node
locked:true , // the color becomes lighter and cannot be selected

3. Pop up the right-click menu and listen to the event ContextMenu on Div

@contextmenu.prevent = ‘onContextMenu’
Be sure to add. Prevent, otherwise it will not work, and there is no in-depth study on why.

4. There have been several strange phenomena, such as:

<input v-if="inputValue.isEditing"
 v-model="inputValue.title"
 @blur="inputBlur"
 @keyup.13 = "inputBlur"
 @click="inputClick"
 autofocus="autofocus"/>
<template v-else>{{inputValue.title}}</template>

If you change the template in the code to span or div, you can’t pop up the right-click menu. By the way, if you want to output pure text in Vue without div or span tags, you can use the template tag

5. Capture the global click and ContextMenu events to close the pop-up context menu

mounted () {
  document.addEventListener('click', this.clearEditingThings)
  document.addEventListener('contextmenu', this.hideContextMenu)
},

beforeDestroyed() {
  document.removeEventListener('click', this.clearEditingThings)
  document.removeEventListener('contextmenu', this.hideContextMenu)
},

Only one menu needs to be reserved and others can be turned off exclusively. Therefore, it is necessary to judge whether the menu needs to be closed

hideContextMenu(event){
  if(event.target !== this.$refs.nodTitle)
  {
    this.contextMenuPoped = false 
  }
},

The ref of Vue is used. If the right-click node is consistent with the current node, the right-click menu will be displayed, otherwise, it will be closed.

Thank you for your patience. For detailed code, please refer to GitHub: https://github.com/vularsoft/studio-ui
If you have any questions, please leave a message.