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(() => {
this.$refs.sss.updateOpened();
this.$refs.sss.updateActiveName();
});
},
},
async 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>