index.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <template>
  2. <!-- 双视图 -->
  3. <div class="myView" :style="{ 'flex-direction': direction }" ref="myView">
  4. <slot name="left" class="myView_Left"></slot>
  5. <div :class="className" data-type="mouse" @mousedown="mousedown" v-show="showView"></div>
  6. <slot name="right" class="myView_Right"></slot>
  7. </div>
  8. </template>
  9. <script>
  10. export default {
  11. props: {
  12. position: {
  13. default: 'row'
  14. },
  15. showView:{
  16. default:true
  17. },
  18. disabled:{
  19. default:false
  20. }
  21. },
  22. data() {
  23. return {
  24. direction: null,
  25. className: 'myView_Middle',
  26. haveIframe:false
  27. }
  28. },
  29. watch: {
  30. position() {
  31. this.directionRule()
  32. this.getShow()
  33. },
  34. showView(){
  35. this.getShow()
  36. },
  37. disabled(){
  38. this.getMouse()
  39. }
  40. },
  41. mounted() {
  42. this.directionRule()
  43. this.getShow()
  44. this.getMouse()
  45. window.addEventListener('resize',this.EventListener)
  46. },
  47. methods: {
  48. // 窗口缩放,内容等比例缩放
  49. EventListener() {
  50. if(!this.showView){
  51. return
  52. }
  53. var dom = this.$refs.myView
  54. let len = dom.childNodes.length
  55. for (var i = 0; i < len; i++) {
  56. if (dom.childNodes[i].getAttribute('data-type') && dom.childNodes[i].getAttribute('data-type') == 'mouse') {
  57. if (this.direction == 'row' || this.direction == 'row-reverse') {
  58. dom.childNodes[i].style.width = '5px'
  59. } else {
  60. dom.childNodes[i].style.width = '100%'
  61. }
  62. } else {
  63. if (this.direction == 'row' || this.direction == 'row-reverse') {
  64. dom.childNodes[i].style.width = (dom.childNodes[i].clientWidth / (dom.clientWidth - 5)) * 100 + '%'
  65. } else {
  66. dom.childNodes[i].style.height = (dom.childNodes[i].clientHeight / (dom.clientHeight - 5)) * 100 + '%'
  67. }
  68. }
  69. }
  70. },
  71. checkIframe(){
  72. if(!this.showView){
  73. return false
  74. }
  75. // 获取所有的 iframe 元素
  76. var iframes = document.getElementsByClassName('myIframe');
  77. if (iframes.length > 0) {
  78. this.haveIframe = true
  79. }
  80. },
  81. changeIframe(display){
  82. // 获取所有的 iframe 元素
  83. var iframes = document.getElementsByClassName('myIframe');
  84. for(var i = 0;i<iframes.length;i++){
  85. iframes[i].style.pointerEvents = display
  86. }
  87. },
  88. getShow(){
  89. var dom = this.$refs.myView
  90. var display = this.showView?'block':'none'
  91. if(!this.showView){
  92. dom.childNodes[0].style.width = '100%'
  93. dom.childNodes[0].style.height = '100%'
  94. }else{
  95. dom.childNodes[0].style.width = '100%'
  96. dom.childNodes[2].style.width = '100%'
  97. dom.childNodes[0].style.height = '100%'
  98. dom.childNodes[2].style.height = '100%'
  99. }
  100. if (this.direction == 'row' || this.direction == 'row-reverse') {
  101. dom.childNodes[1].style.height = '100%'
  102. dom.childNodes[1].style.width = '5px'
  103. } else {
  104. dom.childNodes[1].style.height = '5px'
  105. dom.childNodes[1].style.width = '100%'
  106. }
  107. dom.style.setProperty('--displays',`${display}`)
  108. },
  109. getMouse(){
  110. var dom = this.$refs.myView
  111. var dom2 = dom.querySelector('[data-type="mouse"]')
  112. if(this.disabled){
  113. dom2.classList.add('disabled')
  114. }else{
  115. if(dom2.classList.contains('disabled')){
  116. dom2.classList.remove('disabled')
  117. }
  118. }
  119. },
  120. // 排列方向
  121. directionRule() {
  122. var a = ['row', "row-reverse", "column", "column-reverse"]
  123. if (a.indexOf(this.position) == -1) {
  124. this.direction = 'row'
  125. } else {
  126. this.direction = this.position
  127. }
  128. if (this.direction == 'row' || this.direction == 'row-reverse') {
  129. this.className = 'myView_Middle'
  130. } else {
  131. this.className = 'myView_Middle2'
  132. }
  133. },
  134. // 鼠标按下
  135. mousedown(e) {
  136. // 上一个兄弟
  137. var prev = e.currentTarget.previousElementSibling
  138. // 下一个兄弟
  139. var next = e.currentTarget.nextElementSibling
  140. // 绑定事件的目标元素
  141. var now = e.currentTarget
  142. // 绑定事件目标元素的父级
  143. var box = e.currentTarget.parentNode
  144. // 当事件被触发时鼠标相对于窗口左侧的距离
  145. var startX = e.clientX;
  146. // 目标元素距离左侧的距离
  147. now.left = now.offsetLeft;
  148. // 当事件被触发时鼠标相对于窗口顶部的距离
  149. var startY = e.clientY;
  150. // 目标元素距离顶部的距离
  151. now.Top = now.offsetTop;
  152. this.checkIframe()
  153. // 鼠标拖动
  154. document.onmousemove = (e) => {
  155. window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
  156. if(this.haveIframe){
  157. this.changeIframe('none')
  158. }
  159. var endX = e.clientX;
  160. var endY = e.clientY;
  161. // now.left + 移动的距离 - 整个盒子距离左侧的距离 = 左边区域最后的宽度
  162. var moveLenX = now.left + (endX - startX) - box.offsetLeft;
  163. // now.Top + 移动的距离 - 整个盒子距离上边的距离= 上边区域最后的宽度
  164. var moveLenY = now.Top + (endY - startY) - box.offsetTop;
  165. // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
  166. var maxTX = box.clientWidth - now.offsetWidth;
  167. // 容器宽度 - 上边区域的宽度 = 下边区域的宽度
  168. var maxTY = box.clientHeight - now.offsetHeight;
  169. // 左边区域的最小宽度为150px
  170. if (moveLenX < 150) moveLenX = 150;
  171. //右边区域最小宽度为150px
  172. if (moveLenX > maxTX - 150) moveLenX = maxTX - 150;
  173. // 上边区域的最小宽度为150px
  174. if (moveLenY < 150) moveLenY = 150;
  175. //下边区域最小宽度为150px
  176. if (moveLenY > maxTY - 150) moveLenY = maxTY - 150;
  177. switch(this.direction){
  178. case 'row':
  179. // 设置目标元素距离左侧区域的距离
  180. now.style.left = moveLenX;
  181. prev.style.width = moveLenX + 'px';
  182. now.style.width = '5px'
  183. if (next) {
  184. next.style.width = box.clientWidth - moveLenX - 5 + 'px';
  185. }
  186. break;
  187. case 'row-reverse':
  188. now.style.left = moveLenX;
  189. next.style.width = moveLenX + 'px';
  190. now.style.width = '5px'
  191. if (prev) {
  192. prev.style.width = box.clientWidth - moveLenX - 5 + 'px';
  193. }
  194. break;
  195. case 'column':
  196. // 设置目标元素距离顶部的距离
  197. now.style.top = moveLenY;
  198. // 左侧(上一个)的兄弟元素
  199. prev.style.height = moveLenY + 'px';
  200. now.style.height = '5px'
  201. if (next) {
  202. next.style.height = (box.clientHeight - moveLenY) + 'px';
  203. }
  204. break;
  205. case 'column-reverse':
  206. // 设置目标元素距离顶部的距离
  207. now.style.top = moveLenY;
  208. // 左侧(上一个)的兄弟元素
  209. next.style.height = moveLenY + 'px';
  210. now.style.height = '5px'
  211. if (prev) {
  212. prev.style.height = (box.clientHeight - moveLenY) + 'px';
  213. }
  214. break;
  215. }
  216. }
  217. // 鼠标抬起清空按下及拖动事件
  218. document.onmouseup = (e) => {
  219. if(this.haveIframe){
  220. this.changeIframe('')
  221. }
  222. document.onmouseup = null;
  223. document.onmousemove = null;
  224. }
  225. },
  226. },
  227. deactivated(){
  228. window.removeEventListener('resize',()=>{})
  229. },
  230. beforeDestroy(){
  231. window.removeEventListener('resize',()=>{})
  232. }
  233. }
  234. </script>
  235. <style lang="scss" scoped>
  236. .myView {
  237. --displays:'none';
  238. width: 100%;
  239. height: 100%;
  240. display: flex;
  241. .myView_Middle {
  242. min-width: 5px;
  243. width: 5px;
  244. height: 100%;
  245. background: #dbdbdb;
  246. cursor: col-resize;
  247. pointer-events: auto;
  248. }
  249. .myView_Middle2 {
  250. height: 10px;
  251. width: 100%;
  252. background: #ABABAB;
  253. cursor: row-resize;
  254. pointer-events: auto;
  255. }
  256. .disabled{
  257. cursor: not-allowed;
  258. pointer-events: none;
  259. }
  260. &>:last-child{
  261. display: var(--displays) !important;
  262. // color: red !important;
  263. }
  264. &>*{
  265. overflow: auto;
  266. }
  267. }
  268. </style>