current position:Home>Drag the left column of Vue and keep the right width unchanged; The scroll bar appears

Drag the left column of Vue and keep the right width unchanged; The scroll bar appears

2022-04-29 15:09:13Miss Zhou Jiada

demo Address : Click to download

It encapsulates the left menu of user-defined instructions and common components , The menu effect is double click , Searchable subnodes

The user needs , The menu on the left is loaded at one time ; You can search all the submenu contents under the tree control

1. The menu on the left can be widened or narrowed freely ; The content on the right side remains unchanged , The method I use is the right div Embedded in router-view In order not to zoom

1. The left menu defaults to 200 The width of ; Brace for 15 The width of should be less than 200 Dynamically set the width on the right side when , Don't leave the right side empty

```views
views             
├─ AboutView.vue  
└─ HomeView.vue   

```
---

```components
components            
└─ TreeCode           
   ├─ index copy.vue  
   ├─ index.json      
   └─ index.vue       

```
---

```drag-move
drag-move      
├─ index.js    
└─ index.scss  

```
---

Code up

router file


import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView,
    redirect: '/AboutView',
    children: [
      {
        path: 'AboutView',
        name: 'AboutView',
        component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
      }
    ]
  }
]

const router = new VueRouter({
  routes
})

export default router

HomeView.vue file

<!--
 * @Author: your name
 * @Date: 2022-04-22 22:14:46
 * @LastEditTime: 2022-04-23 14:05:33
 * @LastEditors: Please set LastEditors
 * @Description:  open koroFileHeader Check the configuration   Set it up : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \my-project\src\views\HomeView.vue
-->
<template>
  <div class='only-container'>
    <div class='only-left-sidebar'>
       Left column 
      <tree-code style="width: 100%;height:380px" type="comCode" @node-click="nodeClick" />
    </div>
    <div class='only-resize' title=' Shrink sidebar ' v-drag-move='{setWidth:setWidth}'>⋮</div>
    <div class='only-right'>
       On the right side {
   {rightWidth}}
      <router-view :setWidth="rightWidth"></router-view>
    </div>
  </div>
</template>

<script>
import TreeCode from '@/components/TreeCode/index'
export default {
  components: { TreeCode },
  data () {
    return {
      dialogVisible: false,
      rightWidth: 230
    }
  },
  computed: {
  },
  mounted () {
    // this.dragControllerDiv()
  },

  methods: {
    setWidth (x) {
      console.log('data Settings in ', x);
      this.rightWidth = x;
    },
    nodeClick (data) {
      console.log(' Send a request ', data)
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

AboutView.vue


<template>
  <div class="content" v-bind:style="style">
     Subpage -{
   {style}}
  </div>
</template>
<script>
export default {
  name: 'AboutView',
  props: {
    setWidth: {
      type: [String, Number],
      default: 230
    }
  },
  components: {},
  data () {
    return {
    }
  },
  computed: {
    style () {
      return {
        width: `calc(100vw - ${this.setWidth}px)`
      }
    }
  },
  beforeMount () { },
  mounted () { },
  methods: {},
  watch: {}
}
</script>
<style lang='scss' scoped>
.content {
  background: yellow;
  height: 100%;
}
</style>

TreeCode.vue  Left tree control

<!-- Tree side navigation -->
<template>
  <div v-if="state" class="tree-code" style="height:100%;">
    <div v-loading="rootLoading" style="height: 100%;max-height: 100%;overflow-y: auto">
      <div class="filter-content">
        <el-input placeholder=" Enter keywords to filter " v-model="filterText">
        </el-input>
        <el-button icon="el-icon-search" circle @click="handleSearch"></el-button>
      </div>
      <el-tree ref="tree" :filter-node-method="filterNode" :props="props" :data="loadData" highlight-current node-key="code" size="medium" :expand-on-click-node="false" @node-click="handleNodeClick" @check-change="handleCheckChange" style="height: 100%;overflow: auto" />
    </div>
  </div>
</template>

<script>
import { list } from './index.json'
export default {
  name: 'TreeCode',
  props: {
    type: {
      type: String,
      required: true,
      default: null,
      validator: function (value) {
        // comCode: Affiliation organization 
        // teamCode:  Renewal team 
        return ['comCode', 'teamCode'].indexOf(value) !== -1
      }
    }
  },
  data () {
    return {
      filterText: '',
      treeClickCount: 0, //  Define the number of clicks , Default 0 Time 
      props: {
        label: 'label',
        isLeaf: 'leaf'
      },
      //  Loading or not 
      loading: false,
      //  The root node is loaded 
      rootLoading: false,
      //  state 
      state: true,
      loadData: []
    }
  },
  mounted () {
    // this.loadData = list
    this.getlist()
  },
  methods: {
    getlist () {
      this.rootLoading = true
      //  If the current is a request interface, this method is written to then It's coming in res
      if (this.type == 'comCode') { // The parent component determines which interface to request 
        this.loadData = this.getReturnNode(list)
        console.log(' this.loadData', this.loadData);
        this.rootLoading = false

      }
    },
    getReturnNode (arr) {
      //  Loop traversal 
      for (let i = 0; i < arr.length; i++) {
        arr[i].label = arr[i].text
        arr[i].code = arr[i].id
        //  If there is... In the array children Then continue recursion 
        if (arr[i].children) {
          this.getReturnNode(arr[i].children)
        }
      }
      return arr
    },
    filterNode (value, data, node) {
      if (!value) return true
      let parentNode = node.parent;
      let labels = [node.label];
      let level = 1
      while (level < node.level) {
        labels = [...labels, parentNode.label]
        parentNode = parentNode.parent
        level++
      }
      return labels.some(label => label.indexOf(value) !== -1)
    },
    //  Click handle 
    handleNodeClick (data) {
      //  Record click times 
      this.treeClickCount++
      //  More than one click 2 No treatment for the first time , Go straight back to , It can also be extended to multi hit events 
      if (this.treeClickCount >= 2) {
        return
      }
      //  timer , Calculation 300 Milliseconds , You can modify 
      this.timer = window.setTimeout(() => {
        if (this.treeClickCount == 1) {
          //  Set the number of times to zero 
          this.treeClickCount = 0
          //  Click event handling 
          console.log(' Click events , The corresponding logic can be processed here ')
        } else if (this.treeClickCount > 1) {
          //  Set the number of times to zero 
          this.treeClickCount = 0
          //  Double-click the event 
          console.log(' Double-click the event , The corresponding logic can be processed here ')
          this.$emit('node-click', data)
        }
      }, 300)
    },
    //  Get the multi selected node array 
    handleCheckChange () {
      this.$emit('check-change', this.$refs.tree.getCheckedNodes())
    },
    //  Set the currently checked node 
    setCheckedNodes (list) {
      this.$refs.tree.setCheckedNodes(list)
    },
    //  Reload 
    reload () {
      console.log(' Reload ');
      //  Parent component usage  window.location.reload()
      this.state = false
      this.$nextTick(() => (this.state = true))
    },
    //  Click on the search 
    handleSearch () {
      this.$refs.tree.filter(this.filterText);
    }
  },
  watch: {
    // filterText (val) {// Search on input 
    //   this.$refs.tree.filter(val);
    // }
  }
}
</script>
<style scoped>
.tree-code {
  user-select: none;
}
.filter-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>

Control json

{
  "list": [
    {
      "id": 0,
      "text": " Guangdong Power Grid ",
      "children": [
        {
          "id": "0-1",
          "text": " Staff dormitory "
        },
        {
          "id": "0-2",
          "text": " canteen ",
          "children": [
            {
              "id": "0-2-1",
              "text": " Speed Dome Cameras 1 Number "
            },
            {
              "id": "0-2-2",
              "text": " Speed Dome Cameras 2 Number "
            }
          ]
        }
      ]
    },
    {
      "id": 1,
      "text": " Guangdong Power Grid 2",
      "children": [
        {
          "id": "1-1",
          "text": " Staff dormitory 2"
        },
        {
          "id": "1-2",
          "text": " canteen 2",
          "children": [
            {
              "id": "1-2-1",
              "text": " Speed Dome Cameras 1 Number 2"
            },
            {
              "id": "1-2-2",
              "text": " Speed Dome Cameras 2 Number 2"
            }
          ]
        }
      ]
    }
  ]
}

drag-move.js Custom instruction

/*
 * @Author: your name
 * @Date: 2022-04-23 12:09:47
 * @LastEditTime: 2022-04-23 14:17:00
 * @LastEditors: your name
 * @Description:  open koroFileHeader Check the configuration   Set it up : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \my-project\src\directive\drag-move\index.js
 */

import './index.scss'
const dragMove = {
  inserted: function (el, binding, vnode) {
    const left = document.getElementsByClassName('only-left-sidebar')[0]
    const right = document.getElementsByClassName('only-right')[0]
    el.onmousedown = function (e) {
      const startX = e.clientX
      const resizeLeft = el.offsetLeft
      const parent = document.getElementsByClassName('only-container')[0]
      document.onmousemove = function (e) {
        const moveX = e.clientX
        let moveLen = resizeLeft + (moveX - startX)
        const maxT = parent.clientWidth - el.offsetWidth //  Container width  -  The width of the left area  =  The width of the right area 
        moveLen = moveLen < 10 ? 10 : moveLen //  The width is the smallest area on the left 10px
        moveLen = moveLen > (maxT - 150) ? maxT - 150 : moveLen //  The minimum width of the right area is 150px
        left.style.width = moveLen + 'px'
        right.style.left = moveLen + 'px'
        el.style.left = (moveLen - 5) + 'px'
        if (moveX < 200) { // When it is less than the default value, divide the more width to the right container 
          binding.value.setWidth(moveX + 20)
        }
      };
      document.onmouseup = function () {
        // document.onmousemove = document.onmouseup = null;
        document.onmousemove = null
        document.onmouseup = null
      };
    };
  }
}

const install = function (Vue) {
  Vue.directive('drag-move', dragMove)
}

if (window.Vue) {
  window['drag-move'] = dragMove
  Vue.use(install) // eslint-disable-line
}

dragMove.install = install

export default {
  install
}

Corresponding css

.only-container {
  width: 100%;
  height: 100vh;
  display: flex;
}

/* left div style */
.only-left-sidebar {
  // position: absolute;
  width: 200px;
  // left: 0;
  // top: 55px;
  // bottom: 0;
  background: palevioletred;
}

/* Drag area div style */
.only-resize {
  cursor: col-resize;
  position: absolute;
  left: 200px;
  top: calc(50% - 23px);
  line-height: 80px;
  text-align: center;
  background: #ddd;
  border-radius: 5px;
  width: 10px;
  z-index: 1;
}

/* Drag and drop area mouse over style */
.only-resize:hover {
  background: #ccc;
}

/* On the right side div' style */
.only-right {
  position: absolute;
  left: 208px;
  right: 0;
  bottom: 0;
  background: peru;
  height: 100%;
  // width: calc(100vw - 200px);
}

main.js file


import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import DragMove from '@/directive/drag-move'

Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(DragMove)

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

copyright notice
author[Miss Zhou Jiada],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/119/202204291343431029.html

Random recommended