vue实现动态获取左侧导航宽度,右侧内容动态改变margin值

vue实现动态获取左侧导航宽度,右侧内容动态改变margin值

正常情况下,左侧菜单全部收起来,给个固定宽度即可(子菜单一般不会很多的)

问题:子菜单全部展开的时候 右边内容会被遮挡一部分,不会随着左边菜单的宽度自动改变margin-left值

目前需求:有个菜单是全部文件,下面展示的是所有的文件夹包括文档(会有很多层)

想法:左边菜单宽度变化的时候可以动态的获取宽度,然后设置右边内容的margin-left

想要实现的效果大概是这个样子的:左边菜单我用了el-menu嵌套el-tree**

在这里插入图片描述

目前实现的效果:(因为项目是重构,从一点一点写的,所以先写了一点结构样式出来)
用的是vue2的框架,框架模板在vue2框架模板

在这里插入图片描述
在这里插入图片描述

添加自定义指令,在左边菜单被撑开的时候动态获取到宽度

注意:directives要跟钩子函数同级,有计算属性的话要写在计算属性的前面,我是直接在菜单页中写看了(layout/components/Sidebar/index.vue)

 // 监听左侧菜单自动被撑开时宽度变化
  directives: {
    resize: {
      // 指令的名称
      bind(el, binding) {
        // el为绑定的元素,binding为绑定给指令的对象
        console.log(el, "绑定", binding);
        let _width = "";
        function isReize() {
          const style = document.defaultView.getComputedStyle(el);
          if (_width !== style.width) {
            binding.value({ width: style.width, targetId: el.id });
            _width = style.width;
          }
        }
        el.__vueSetInterval__ = setInterval(isReize, 300);
      },
      unbind(el) {
        console.log(el, "解绑");
        clearInterval(el.__vueSetInterval__);
      },
    },
  },

methods中的方法动态给右侧内容赋值margin-left

methods: {
    MuneResize(data) {
      // 拿到左侧菜单父元素
      const leftDom = document.getElementById(`${data.targetId}`);
      // 拿到右侧内容父元素
      const mainContainer =
        document.getElementsByClassName("main-container")[0];
      mainContainer.style.marginLeft = leftDom.clientWidth + "px";
    },
  },

最后在左侧菜单父元素上使用自定义指令
在这里插入图片描述
实现效果:右侧内容的margin-left值会根据左侧菜单的宽度自动改变
在这里插入图片描述

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue实现动态计算宽度可以使用 `ref` 来获取到对应元素的DOM对象,然后通过 `offsetWidth` 属性来获取元素的实际宽度,最后将宽度动态绑定到元素的 `style` 属性中即可。 例如,假设有一个动态生成的菜单列表,每个菜单项的宽度不一定相同,我们可以在模板中为每个菜单项添加一个 `ref` 属性,然后在 `mounted` 钩子函数中通过 `this.$refs` 获取到每个菜单项的DOM对象,计算它们的实际宽度并保存到一个数组中,最后将这个数组绑定到菜单列表的 `style` 属性中,实现动态计算宽度。 具体代码如下: ``` <template> <div class="menu" :style="{width: menuWidth + 'px'}"> <div v-for="(item, index) in menuList" :key="index" :ref="'menuItem' + index" class="menu-item">{{ item }}</div> </div> </template> <script> export default { data() { return { menuList: ['Home', 'Products', 'About', 'Contact'], menuItemWidths: [] } }, computed: { menuWidth() { return this.menuItemWidths.reduce((total, width) => total + width, 0) } }, mounted() { this.menuItemWidths = this.menuList.map((item, index) => { return this.$refs['menuItem' + index][0].offsetWidth }) } } </script> ``` 在上面的代码中,我们通过 `map` 函数遍历菜单列表,获取到每个菜单项的DOM对象,然后通过 `offsetWidth` 属性获取它们的实际宽度,最后将宽度保存到 `menuItemWidths` 数组中。然后在 `menuWidth` 计算属性中,我们使用 `reduce` 函数将所有菜单项的宽度相加得到菜单的总宽度,最后将这个宽度绑定到菜单列表的 `style` 属性中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值