6
\$\begingroup\$

I just started Developing Web App (Vue.js) for my company for around 1-2 months. Therefore, my knowledge and experience in HTML, CSS and Javascript is kinda shallow.

I've created a custom resizable split DIVs and it working just fine as what I wanted. However, I would like to know if my code is a good code or a bad code.

Live demo

var dividerRef = '';
var currentDivider = null;

var leftDivider = null;
var rightDivider = null;
var leftRightDivider = null;

var topLeft = null;
var topRight = null;
var bottomLeft = null;
var bottomRight = null;

var app = new Vue({
  el: '#app',
  methods: 
  {
		dividerDragStart: function(e) {
			e.dataTransfer.setDragImage(new Image, 0, 0);
		},
    dividerDrag: function(e) {
			if (dividerRef == 'lrDivider') {
				currentDivider.style.left = e.clientX + 'px';

				leftDivider.style.width = (e.clientX + 2) + 'px';

				rightDivider.style.left = (e.clientX) + 'px';
				rightDivider.style.width = (window.innerWidth - e.clientX + 2) + 'px';

				topLeft.style.width = e.clientX + 'px';
				bottomLeft.style.width = e.clientX + 'px';

				topRight.style.left = e.clientX + 'px';
				topRight.style.width = (window.innerWidth - e.clientX + 2) + 'px';
				bottomRight.style.left = e.clientX + 'px';
				bottomRight.style.width = (window.innerWidth - e.clientX + 2) + 'px';
			} else if (dividerRef == 'rtbDivider') {
				currentDivider.style.top = (e.clientY) + 'px';

				topRight.style.height = (e.clientY) + 'px'

				bottomRight.style.height = (window.innerHeight - e.clientY) + 'px';
				bottomRight.style.top = (e.clientY) + 'px';
			} else if (dividerRef == 'ltbDivider') {
				currentDivider.style.top = (e.clientY) + 'px';

				topLeft.style.height = (e.clientY) + 'px'

				bottomLeft.style.height = (window.innerHeight - e.clientY) + 'px';
				bottomLeft.style.top = (e.clientY) + 'px';
			}
		},
		dividerMouseDown: function(name) {
			dividerRef = name;
			currentDivider = this.$refs[dividerRef];
		},
		dividerDragEnd: function(e) {
			if (dividerRef == 'lrDivider') {
				currentDivider.style.left = e.clientX + 'px';
				leftDivider.style.width = (e.clientX + 2) + 'px';

				rightDivider.style.left = (e.clientX) + 'px';
				rightDivider.style.width = (window.innerWidth - e.clientX + 2) + 'px';

				topLeft.style.width = e.clientX + 'px';
				bottomLeft.style.width = e.clientX + 'px';

				topRight.style.left = e.clientX + 'px';
				topRight.style.width = (window.innerWidth - e.clientX + 2) + 'px';
				bottomRight.style.left = e.clientX + 'px';
				bottomRight.style.width = (window.innerWidth - e.clientX + 2) + 'px';
			} else if (dividerRef == 'rtbDivider') {
				currentDivider.style.top = (e.clientY) + 'px';

				topRight.style.height = (e.clientY) + 'px'

				bottomRight.style.height = (window.innerHeight - e.clientY) + 'px';
				bottomRight.style.top = (e.clientY) + 'px';
			} else if (dividerRef == 'ltbDivider') {
				currentDivider.style.top = (e.clientY) + 'px';

				topLeft.style.height = (e.clientY) + 'px'

				bottomLeft.style.height = (window.innerHeight - e.clientY) + 'px';
				bottomLeft.style.top = (e.clientY) + 'px';
			}

			dividerRef = '';
			currentDivider = null;
		}
  },
  mounted() {
    topLeft = this.$refs.topLeft;
    topRight = this.$refs.topRight;
    bottomLeft = this.$refs.bottomLeft;
    bottomRight = this.$refs.bottomRight;

    var heightHalf = (window.innerHeight - 80) / 2;
		var widthHalf = window.innerWidth / 2;
		
		leftDivider = this.$refs.ltbDivider;
		rightDivider = this.$refs.rtbDivider;
		leftRightDivider = this.$refs.lrDivider;
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div>
    <div class="top-left" ref="topLeft">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>
      </div>
    </div>
    <div class="top-right" ref="topRight">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>
      </div>
    </div>
    <div class="bottom-left" ref="bottomLeft">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>
      </div>
    </div>
    <div class="bottom-right" ref="bottomRight">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>
      </div>
    </div>

    <div class="left-right divider" ref="lrDivider" @mousedown="dividerMouseDown('lrDivider')" draggable="true"
        @drag="dividerDrag" @dragend="dividerDragEnd" @dragstart="dividerDragStart"></div>
    <div class="right-top-bottom divider" ref="rtbDivider" @mousedown="dividerMouseDown('rtbDivider')" draggable="true"
        @drag="dividerDrag" @dragend="dividerDragEnd" @dragstart="dividerDragStart"></div>
    <div class="left-top-bottom divider" ref="ltbDivider" @mousedown="dividerMouseDown('ltbDivider')" draggable="true"
        @drag="dividerDrag" @dragend="dividerDragEnd" @dragstart="dividerDragStart"></div>
  </div>
</div>

\$\endgroup\$
2
\$\begingroup\$

Alternative to directly modifying style of DOM element

With VueJS, there are often ways of manipulating DOM elements without needing to reference them via properties like id or ref. One way is to use computed properties and bound styles. See rewritten code below for examples.

Reviewing current code

This code relies heavily on global variables (e.g. dividerRef, currentDivider, leftDivider, rightDivider, etc.). Unless those variables are needed for other code, the Vue instance's data object can be used to store properties used within the various methods.

The code is somewhat difficult to read because indentation is inconsistent. Particularly lines like these:

var app = new Vue({
  el: '#app',
  methods: 
  {
                dividerDragStart: function(e) {
                    e.dataTransfer.setDragImage(new Image, 0, 0);
                },
    dividerDrag: function(e) {
                        if (dividerRef == 'lrDivider') {
                                currentDivider.style.left = e.clientX + 'px';

It is best to keep indentation consistent - e.g. two or four spaces or single tab per nesting level.

There is a lot of duplicated code in methods dividerDrag() and dividerDragEnd() - all lines except the last few of the latter function appear to be repeated, and dividerDragEnd could just call dividerDrag (which could be renamed to avoid confusion) or those duplicate lines could be abstracted out to a separate function that can be called by both.

Variables heightHalf and widthHalf appear to be unused after being assigned a value in the mounted method. Those can be removed.

The CSS for the <div> elements that contain the text-area elements could be consolidated - e.g. give them all a class called container:

.container {
  position: absolute;
  overflow: scroll;
  top: 0;
  left: 0;
  height: 50%;
  width: 50%;
}

Then the existing styles can be simplified to simple colors and position overrides:

top-left {
  background-color: pink;
}

.top-right {
  background-color: lightgreen;
  left: 50%;
}

.bottom-left {
  background-color: lightblue;
  top: 50%;
}

.bottom-right {
  background-color: lightyellow;
  top: 50%;
  left: 50%;
}

Alternative approach

As mentioned above, computed properties and bound styles can be used to manipulate the DOM elements instead of referencing the DOM elements by ref attributes.

Notice the data property of the vue instance contains three values, initially set to empty strings, to store the positions of the dividers. When the dividers are dragged, those properties get updated accordingly. Then the computed values for the styles will be changed automatically.

With this approach, there are only four small methods needed to handle the drag events, and there is no need to have methods bound to the dragend or mousedown events on the dividers. All of the style properties are computed after the data values are updated.

var app = new Vue({
  el: '#app',
  data: {
    lrDividerPos: '',
    rtbDividerPos: '',
    ltbDividerPos: '',
  },
  computed: {
    bottomLeftStyle: function() {
      const style = {};
      if (this.lrDividerPos) {
        style.width = this.lrDividerPos + 'px';
      }
      if (this.ltbDividerPos) {
        style.height = (window.innerHeight - this.ltbDividerPos) + 'px';
        style.top = this.ltbDividerPos + 'px';
      }
      return style;
    },
    bottomRightStyle: function() {
      const style = {};
      if (this.lrDividerPos) {
        style.left = this.lrDividerPos + 'px';
        style.width = (window.innerWidth - this.lrDividerPos + 2) + 'px';
      }
      if (this.rtbDividerPos) {
        style.top = this.rtbDividerPos + 'px';
        style.height = (window.innerHeight - this.rtbDividerPos) + 'px';
      }
      return style;
    },
    leftDividerStyles: function() {
      if (this.lrDividerPos) {
        return {
          width: (this.lrDividerPos + 2) + 'px'
        };
      }
      return {};
    },
    ltbDividerStyles: function() {
      const style = {};
      if (this.lrDividerPos) {
        style.width = this.lrDividerPos + 2 + 'px';
      }
      if (this.ltbDividerPos) {
        style.top = this.ltbDividerPos + 'px';
      }
      return style;
    },
    lrDividerStyles: function() {
      if (this.lrDividerPos) {
        return {
          left: this.lrDividerPos + 'px'
        };
      }
      return {};
    },
    rtbDividerStyles: function() {
      const style = {};
      if (this.lrDividerPos) {
        style.left = this.lrDividerPos + 'px';
        style.width = (window.innerWidth - this.lrDividerPos + 2) + 'px';
      }
      if (this.rtbDividerPos) {
        style.top = this.rtbDividerPos + 'px';
      }
      return style;
    },
    topLeftStyle: function() {
      const style = {};
      if (this.ltbDividerPos) {
        style.height = this.ltbDividerPos + 'px';
      }
      if (this.lrDividerPos) {
        style.width = this.lrDividerPos + 'px';
      }
      return style;
    },
    topRightStyle: function() {
      const style = {};
      if (this.lrDividerPos) {
        style.left = this.lrDividerPos + 'px';
        style.width = (window.innerWidth - this.lrDividerPos + 2) + 'px';
      }
      if (this.rtbDividerPos) {
        style.height = this.rtbDividerPos + 'px';
      }
      return style;
    }
  },
  methods: {
    lrDividerDrag: function(e) {
      if (e.clientX) {
        this.lrDividerPos = e.clientX;
      }
    },
    ltbDividerDrag: function(e) {
      if (e.clientY) {
        this.ltbDividerPos = e.clientY;
      }
    },
    rtbDividerDrag: function(e) {
      if (e.clientY) {
        this.rtbDividerPos = e.clientY;
      }
    },
    dividerDragStart: function(e) {
      e.dataTransfer.setDragImage(new Image, 0, 0);
    }
  }
});
.text-area {
  margin: 10px;
}

.top-left {
  position: absolute;
  background-color: pink;
  overflow: scroll;
  top: 0;
  left: 0;
  height: 50%;
  width: 50%;
}

.top-right {
  position: absolute;
  background-color: lightgreen;
  overflow: scroll;
  top: 0;
  left: 50%;
  height: 50%;
  width: 50%;
}

.bottom-left {
  position: absolute;
  background-color: lightblue;
  overflow: scroll;
  top: 50%;
  left: 0;
  height: 50%;
  width: 50%;
}

.bottom-right {
  position: absolute;
  background-color: lightyellow;
  overflow: scroll;
  top: 50%;
  left: 50%;
  height: 50%;
  width: 50%;
}

.divider {
  position: absolute;
  background-color: black;
}

.left-right {
  width: 4px;
  height: 100%;
  top: 0;
  left: calc(50% - 4px / 2);
}

.right-top-bottom {
  width: 50%;
  height: 4px;
  top: calc(50% - 4px / 2);
  left: 50%;
}

.left-top-bottom {
  width: 50%;
  height: 4px;
  top: calc(50% - 4px / 2);
  left: 0;
}

.left-right:hover {
  cursor: col-resize;
}

.left-top-bottom:hover,
.right-top-bottom:hover {
  cursor: row-resize;
}

::-webkit-scrollbar {
  height: 0;
  width: 0;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <div>
    <div class="top-left" :style="topLeftStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>
    <div class="top-right" :style="topRightStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>
    <div class="bottom-left" :style="bottomLeftStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>
    <div class="bottom-right" :style="bottomRightStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>

    <div class="left-right divider" draggable="true" @dragstart="dividerDragStart" @drag="lrDividerDrag" :style="lrDividerStyles"></div>
    <div class="right-top-bottom divider" draggable="true" @drag="rtbDividerDrag" @dragstart="dividerDragStart" :style="rtbDividerStyles"></div>
    <div class="left-top-bottom divider" draggable="true" @drag="ltbDividerDrag" @dragstart="dividerDragStart" :style="ltbDividerStyles"></div>
  </div>
</div>

The computed properties could be simplified using shorthand notations and ternary operators. For example, instead of conditionally setting properties on each object, always apply it and the browser will accept it if it is a valid rule. For some rules, a ternary operator can be used to either add a value or an empty string - e.g.

instead of

ltbDividerStyles: function() {
  const style = {};
  if (this.lrDividerPos) {
    style.width = this.lrDividerPos + 2 + 'px';
  }
  if (this.ltbDividerPos) {
    style.top = this.ltbDividerPos + 'px';
  }
  return style;
},

it can be simplified to:

    ltbDividerStyles: function() {
      return {
        top: this.ltbDividerPos + 'px',
        width: this.lrDividerPos ? this.lrDividerPos + 2 + 'px' : ''
      };
    },

Full simplification:

computed: {
    bottomLeftStyle: function() {  
      return {
        height: (window.innerHeight - this.ltbDividerPos) + 'px',
        top: this.ltbDividerPos + 'px',
        width: this.lrDividerPos + 'px'
      };
    },
    bottomRightStyle: function() {
      return {
        height: (window.innerHeight - this.rtbDividerPos) + 'px',
        left: this.lrDividerPos + 'px',
        top: this.rtbDividerPos + 'px', 
        width: (window.innerWidth - this.lrDividerPos + 2) + 'px'
      };
    }, 
    leftDividerStyles: function() {
      return {width: (this.lrDividerPos + 2) + 'px'};
    },
    ltbDividerStyles: function() {
      return {
        top: this.ltbDividerPos + 'px',
        width: this.lrDividerPos ? this.lrDividerPos + 2 + 'px' : ''
      };
    },
    lrDividerStyles: function() {
      return {left: this.lrDividerPos + 'px'};
    },
    rtbDividerStyles: function() {
      return {
        left: this.lrDividerPos + 'px',
        top: this.rtbDividerPos + 'px',
        width: (window.innerWidth - this.lrDividerPos + 2) + 'px'
      };
    },
    topLeftStyle: function() {  
      return {
        height: this.ltbDividerPos + 'px',
        width: this.lrDividerPos + 'px'
      };
    },
    topRightStyle: function() {
      return {
        height: this.rtbDividerPos + 'px',
        left: this.lrDividerPos + 'px',
        width: (window.innerWidth - this.lrDividerPos + 2) + 'px'
      };
    }
  },

Another option might be to use negative values for the initial divider position values in the data property, and only if those values are non-negative use them in the computed properties.

var app = new Vue({
  el: '#app',
  data: {
    lrDividerPos: -1,
    rtbDividerPos: -1,
    ltbDividerPos: -1,
  },
  computed: {
    bottomLeftStyle: function() {
      return {
        height: this.ltbDividerPos > -1 ? (window.innerHeight - this.ltbDividerPos) + 'px' : '',
        top: this.ltbDividerPos > -1 ? this.ltbDividerPos + 'px' : '',
        width: this.lrDividerPos > -1 ? this.lrDividerPos + 'px' : ''
      };
    },
    bottomRightStyle: function() {
      return {
        height: this.rtbDividerPos > -1 ? (window.innerHeight - this.rtbDividerPos) + 'px' : '',
        left: this.lrDividerPos > -1 ? this.lrDividerPos + 'px' : '',
        top: this.rtbDividerPos > -1 ? this.rtbDividerPos + 'px' : '',
        width: this.lrDividerPos > -1 ? (window.innerWidth - this.lrDividerPos + 2) + 'px' : ''
      };
    },
    leftDividerStyles: function() {
      return {
        width: this.lrDividerPos > -1 ? (this.lrDividerPos + 2) + 'px' : ''
      };
    },
    ltbDividerStyles: function() {
      return {
        top: this.ltbDividerPos > -1 ? this.ltbDividerPos + 'px' : '',
        width: this.lrDividerPos > -1 ? this.lrDividerPos + 2 + 'px' : ''
      };
    },
    lrDividerStyles: function() {
      return {
        left: this.lrDividerPos > -1 ? this.lrDividerPos + 'px' : ''
      };
    },
    rtbDividerStyles: function() {
      return {
        left: this.lrDividerPos > -1 ? this.lrDividerPos + 'px' : '',
        top: this.rtbDividerPos > -1 ? this.rtbDividerPos + 'px' : '',
        width: this.lrDividerPos > -1 ? (window.innerWidth - this.lrDividerPos + 2) + 'px' : ''
      };
    },
    topLeftStyle: function() {
      return {
        height: this.ltbDividerPos > -1 ? this.ltbDividerPos + 'px' : '',
        width: this.lrDividerPos > -1 ? this.lrDividerPos + 'px' : ''
      };
    },
    topRightStyle: function() {
      return {
        height: this.rtbDividerPos > -1 ? this.rtbDividerPos + 'px' : '',
        left: this.lrDividerPos > -1 ? this.lrDividerPos + 'px' : '',
        width: this.lrDividerPos > -1 ? (window.innerWidth - this.lrDividerPos + 2) + 'px' : ''
      };
    }
  },
  methods: {
    lrDividerDrag: function(e) {
      if (e.clientX) {
        this.lrDividerPos = e.clientX;
      }
    },
    ltbDividerDrag: function(e) {
      if (e.clientY) {
        this.ltbDividerPos = e.clientY;
      }
    },
    rtbDividerDrag: function(e) {
      if (e.clientY) {
        this.rtbDividerPos = e.clientY;
      }
    },
    dividerDragStart: function(e) {
      e.dataTransfer.setDragImage(new Image, 0, 0);
    }
  }
});
.text-area {
  margin: 10px;
}

.top-left {
  position: absolute;
  background-color: pink;
  overflow: scroll;
  top: 0;
  left: 0;
  height: 50%;
  width: 50%;
}

.top-right {
  position: absolute;
  background-color: lightgreen;
  overflow: scroll;
  top: 0;
  left: 50%;
  height: 50%;
  width: 50%;
}

.bottom-left {
  position: absolute;
  background-color: lightblue;
  overflow: scroll;
  top: 50%;
  left: 0;
  height: 50%;
  width: 50%;
}

.bottom-right {
  position: absolute;
  background-color: lightyellow;
  overflow: scroll;
  top: 50%;
  left: 50%;
  height: 50%;
  width: 50%;
}

.divider {
  position: absolute;
  background-color: black;
}

.left-right {
  width: 4px;
  height: 100%;
  top: 0;
  left: calc(50% - 4px / 2);
}

.right-top-bottom {
  width: 50%;
  height: 4px;
  top: calc(50% - 4px / 2);
  left: 50%;
}

.left-top-bottom {
  width: 50%;
  height: 4px;
  top: calc(50% - 4px / 2);
  left: 0;
}

.left-right:hover {
  cursor: col-resize;
}

.left-top-bottom:hover,
.right-top-bottom:hover {
  cursor: row-resize;
}

::-webkit-scrollbar {
  height: 0;
  width: 0;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <div>
    <div class="top-left" :style="topLeftStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>
    <div class="top-right" :style="topRightStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>
    <div class="bottom-left" :style="bottomLeftStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>
    <div class="bottom-right" :style="bottomRightStyle">
      <div class="text-area">
        <h3>Resize me using the black bars</h3>

        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
        in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
    </div>

    <div class="left-right divider" draggable="true" @dragstart="dividerDragStart" @drag="lrDividerDrag" :style="lrDividerStyles"></div>
    <div class="right-top-bottom divider" draggable="true" @drag="rtbDividerDrag" @dragstart="dividerDragStart" :style="rtbDividerStyles"></div>
    <div class="left-top-bottom divider" draggable="true" @drag="ltbDividerDrag" @dragstart="dividerDragStart" :style="ltbDividerStyles"></div>
  </div>
</div>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.