IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue 左侧栏拖拽右侧宽度不变;出现滚动条 -> 正文阅读

[JavaScript知识库]vue 左侧栏拖拽右侧宽度不变;出现滚动条

demo地址:点击下载

其中封装了自定义指令及公共组件的左侧菜单,菜单效果为双击,可搜索子节点

用户需求,左侧菜单为一次加载出来;可以搜索树控件下所有的子菜单内容

1.左侧菜单可以自由拉宽缩小;右侧内容不变,本人用到的方法是右侧div中嵌入router-view才能做到不缩放

1.左侧菜单默认为200的宽;拉条为15的宽当小于200的时候右侧动态设置宽度,不让右侧空出来

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

```
---

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

```
---

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

```
---

上代码

router文件


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文件

<!--
 * @Author: your name
 * @Date: 2022-04-22 22:14:46
 * @LastEditTime: 2022-04-23 14:05:33
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: 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'>
      左侧栏
      <tree-code style="width: 100%;height:380px" type="comCode" @node-click="nodeClick" />
    </div>
    <div class='only-resize' title='收缩侧边栏' v-drag-move='{setWidth:setWidth}'>?</div>
    <div class='only-right'>
      右侧{{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中的设置', x);
      this.rightWidth = x;
    },
    nodeClick (data) {
      console.log('发送请求', data)
    }
  }
}
</script>

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

AboutView.vue


<template>
  <div class="content" v-bind:style="style">
    子页面-{{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?左侧树控件

<!--树形侧边导航-->
<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="输入关键字进行过滤" 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:归属机构
        // teamCode: 续保团队
        return ['comCode', 'teamCode'].indexOf(value) !== -1
      }
    }
  },
  data () {
    return {
      filterText: '',
      treeClickCount: 0, // 定义点击次数,默认0次
      props: {
        label: 'label',
        isLeaf: 'leaf'
      },
      // 是否加载中
      loading: false,
      // 根节点加载
      rootLoading: false,
      // 状态
      state: true,
      loadData: []
    }
  },
  mounted () {
    // this.loadData = list
    this.getlist()
  },
  methods: {
    getlist () {
      this.rootLoading = true
      // 如果当前是请求接口那么这个方法写到then里面传入res
      if (this.type == 'comCode') { //父组件判断请求哪个接口
        this.loadData = this.getReturnNode(list)
        console.log(' this.loadData', this.loadData);
        this.rootLoading = false

      }
    },
    getReturnNode (arr) {
      // 循环遍历
      for (let i = 0; i < arr.length; i++) {
        arr[i].label = arr[i].text
        arr[i].code = arr[i].id
        // 如果数组中有children则继续递归
        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)
    },
    // 点击处理
    handleNodeClick (data) {
      // 记录点击次数
      this.treeClickCount++
      // 单次点击次数超过2次不作处理,直接返回,也可以拓展成多击事件
      if (this.treeClickCount >= 2) {
        return
      }
      // 计时器,计算300毫秒为单位,可自行修改
      this.timer = window.setTimeout(() => {
        if (this.treeClickCount == 1) {
          // 把次数归零
          this.treeClickCount = 0
          // 单击事件处理
          console.log('单击事件,可在此处理对应逻辑')
        } else if (this.treeClickCount > 1) {
          // 把次数归零
          this.treeClickCount = 0
          // 双击事件
          console.log('双击事件,可在此处理对应逻辑')
          this.$emit('node-click', data)
        }
      }, 300)
    },
    // 获取多选节点数组
    handleCheckChange () {
      this.$emit('check-change', this.$refs.tree.getCheckedNodes())
    },
    // 设置目前勾选的节点
    setCheckedNodes (list) {
      this.$refs.tree.setCheckedNodes(list)
    },
    // 重新加载
    reload () {
      console.log('重新加载');
      // 父组件用法 window.location.reload()
      this.state = false
      this.$nextTick(() => (this.state = true))
    },
    // 点击搜索
    handleSearch () {
      this.$refs.tree.filter(this.filterText);
    }
  },
  watch: {
    // filterText (val) {//输入时搜索
    //   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>

控件下对应的本地json

{
  "list": [
    {
      "id": 0,
      "text": "广东电网",
      "children": [
        {
          "id": "0-1",
          "text": "员工宿舍"
        },
        {
          "id": "0-2",
          "text": "食堂",
          "children": [
            {
              "id": "0-2-1",
              "text": "球机1号"
            },
            {
              "id": "0-2-2",
              "text": "球机2号"
            }
          ]
        }
      ]
    },
    {
      "id": 1,
      "text": "广东电网2",
      "children": [
        {
          "id": "1-1",
          "text": "员工宿舍2"
        },
        {
          "id": "1-2",
          "text": "食堂2",
          "children": [
            {
              "id": "1-2-1",
              "text": "球机1号2"
            },
            {
              "id": "1-2-2",
              "text": "球机2号2"
            }
          ]
        }
      ]
    }
  ]
}

drag-move.js自定义指令

/*
 * @Author: your name
 * @Date: 2022-04-23 12:09:47
 * @LastEditTime: 2022-04-23 14:17:00
 * @LastEditors: your name
 * @Description: 打开koroFileHeader查看配置 进行设置: 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 // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
        moveLen = moveLen < 10 ? 10 : moveLen // 左边区域最小宽度为10px
        moveLen = moveLen > (maxT - 150) ? maxT - 150 : moveLen // 右边区域最小宽度为150px
        left.style.width = moveLen + 'px'
        right.style.left = moveLen + 'px'
        el.style.left = (moveLen - 5) + 'px'
        if (moveX < 200) { //小于默认值的时候把多于的宽度分给右侧容器
          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
}

对应的css

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

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

/*拖拽区div样式*/
.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;
}

/*拖拽区鼠标悬停样式*/
.only-resize:hover {
  background: #ccc;
}

/*右侧div'样式*/
.only-right {
  position: absolute;
  left: 208px;
  right: 0;
  bottom: 0;
  background: peru;
  height: 100%;
  // width: calc(100vw - 200px);
}

main.js文件


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')

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:20:29  更:2022-04-24 09:22:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:23:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码