Vue使用iview中menu菜单组件的大坑!

Vue2使用iview中menu菜单组件的大坑!

在使用iview的menu组件时,当需要发送请求获取菜单,动态渲染组件的时候,会出现设置默认展开菜单无效的bug。
官网给出的方法如下
方法名说明参数
updateOpened手动更新展开的子目录,注意要在 $nextTick 里调用
updateActiveName手动更新当前选择项,注意要在 $nextTick 里调用
官网给出的方法不够具体,如果在vue2中使用,是需要考虑生命周期的问题。
重点:动态渲染的menu组件并设置初始展开的菜单时一定要在created生命周期中使用,因为在这个生命周期中DOM被渲染了但并未挂载到页面中产生实例,所以是获取不到DOM的,所以在这个生命周期后才可以对默认展开菜单进行赋值,并在watch中声明使用nextTick方法,将已经被ref绑定的menu进行侦听更新。
注意:在发送请求时,它的回调也要直接写在created生命周期中,不能写在methods中,而且用了async和await也不行,我觉得这是ivew一个天大的bug。

完整代码

<template>
  <div class="layout">
    <Layout>
      <Header>
        <Menu mode="horizontal" theme="dark" active-name="1">
          <div class="layout-logo"></div>
          <div class="layout-nav">
            <MenuItem name="1" style="font-size: 20px"> 后台管理系统 </MenuItem>
          </div>
          <div
            style="
              font-size: 20px;
              text-align: right;
              color: #fff;
              padding-right: 30px;
           "
          >
            <el-dropdown>
              <i
                class="el-icon-user"
                style="margin-right: 15px; color: #fff; cursor: pointer"
              ></i>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>
                  <span>退出</span>
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
            {{ username }}
          </div>
        </Menu>
      </Header>
      <Layout>
        <Sider hide-trigger :style="{ background: '#fff' }">
          <Menu
            :Ptheme="theme2"
            :active-name="activeName"
            :open-names="[openName]"
            width="auto"
            ref="sss"
          >
            <MenuItem name="2-1" to="">
              <Icon type="ios-home-outline" />首页</MenuItem
            >
            <Submenu
              v-for="(item, index) in navRouter"
              :key="index"
              :name="item.name"
           
            >
              <template slot="title">
                <Icon :type="item.icon" />
                {{ item.name }}
              </template>
              <MenuItem
                id="select"
                v-for="(child, key) in item.children"
                :key="key"
                :to="child.path"
                :name="child.name"
                >{{ child.name }}</MenuItem
              >
            </Submenu>
          </Menu>
        </Sider>
        <Layout :style="{ padding: '0 15px 15px' }">
          <Breadcrumb :style="{ margin: '10px 0' }"> </Breadcrumb>
          <Content
            :style="{ Width: '100%', minHeight: '80vh', background: '#fff' }"
          >
            <router-view></router-view>
          </Content>
        </Layout>
      </Layout>
    </Layout>
  </div>
</template>

<script>
import { getMenu } from "@/api/menuApi";
export default {
  data() {
    return {
      theme2: "light",
      activeName: "", //打开的子标签
      openName: "", //打开的父标签名称
      username: "",
      navRouter: [],
    };
  },
  watch: {
    openName() {
      this.$nextTick(() => {
        //sss 是在menu组件绑定的
        this.$refs.sss.updateOpened();
        this.$refs.sss.updateActiveName();
      });
    },
  },
  async created() {
  //iview menu 动态渲染一定要在created这个声明周期中
    await getMenu().then((ret) => {//请求接口
      this.navRouter = ret.data;
      this.findOpenName(ret.data);
    });
  },
  methods: {
    findOpenName(data) {
      this.activeName = this.$route.name ? this.$route.name : "订单管理";
      data.forEach((element) => {
        element.children.forEach((item) => {
          if (item.name == this.activeName) {
            this.openName = element.name;
          }
        });
      });
    },   
  },
};
</script>
<style lang="sass" scoped>
*
  text-decoration: none
.ivu-layout

  background: #eff2f5 !important

.layout
  width: 100%
  height: 100%

.hw
  height: 500px
  width: 200px
</style>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值