iview2.0中动态生成Menu时,设置activeName不生效的解决办法

原创
2017/06/21 23:47
阅读数 7.6K

    最初的核心代码,最终代码将在本文最后贴出。

<template>
                <Menu theme="light" :activeName="activeKey" @on-select="select">
                    <Menu-group v-for="sy_menu in menus" :title="sy_menu.name">
                        <Menu-item v-for="sy_it in sy_menu.children" :name="sy_it.opname">
                            <Icon :type="sy_it.icon"></Icon>&nbsp;{{sy_it.name}}
                        </Menu-item>
                    </Menu-group>
                </Menu>
</template>
<script>
    export default {
        data(){
            return {
                activeKey    : '',
                menus        : []
            };
        },
        mounted() {
            // 获取菜单
            let that = this;

            axios.post("/admin/menu/menus.html").then(function (res) {
                that.menus = res.data;
            });
            that.activeKey = that.$route.name;
        },
        methods: {
            handleStart () {
                this.$Modal.info({
                    title: '温馨提示',
                    content: '功能待完善,敬请期待!'
                });
            },
            select(n){
                this.$router.push({name:n});
            }
        }
    }
</script>

    iView2.0 动态生成Menu时,通过

<Menu theme="light" :activeName="activeKey" @on-select="select"></Menu>

设置后,始终无效果,而拷贝官网提供的案例,却是没有问题。

于是,将activeName写死,发现无果。

Google了一番,网上只有三条记录相符,查看其中有一条记录,

有人提议,将动态获取的数据放在created中,这个主要是vue强调生命周期。vue的生命周期如下图:

于是,我将动态获取菜单列表的方法放在created中,设置选中菜单的代码放在mounted中,

现在的js部分代码如下:


        created() {
            // 获取菜单
            let that = this;

            axios.post("/admin/menu/menus.html").then(function (res) {
                that.menus = res.data;
            });
        },
        mounted(){
            let that = this;
            that.activeKey = that.$route.name;
         }

发现还是不对,不能选中,实在没有办法了,就想到应该是设置初始选中的菜单,应该是数据加载完成之后才能进行的,而此时数据应该是未加载完成的,

就修改代码为如下情况:


        created() {
            // 获取菜单
            let that = this;

            axios.post("/admin/menu/menus.html").then(function (res) {
                that.menus = res.data;
            });
        },
        mounted(){
            let that = this;
            setTimeout(function(){
                that.activeKey = that.$route.name;
            },5000);
         }

等了5s后发现,出现了自己想要的结果。我大概明白什么原因了,但是让等待5s并不是最佳答案。

于是就想到axios加载完成之后会有一个加载完成的事件。

就继续Google一番,

发现了finally;加入之后,核心代码如下:


        created() {
            // 获取菜单
            let that = this;

            axios.post("/admin/menu/menus.html").then(function (res) {
                that.menus = res.data;
            }).finally(function (w) {
                that.activeKey = that.$route.name;
            });
        },

如果console报错了,

那么就是你的finally模块未正确引入。下面的方法是引入axios finally的方法,如果已经引入,可以不管。

第一步:

npm install axios promise.prototype.finally --save

此时,你将会发现:

第二步,在需要使用finally的Axios前增加一行引入

require('promise.prototype.finally').shim();

再次刷新,发现大功告成。

完整的代码如下:

<style scoped>
    .layout{
        border: 1px solid #d7dde4;
        background: #f5f7f9;
        position: relative;
        border-radius: 4px;
        overflow: hidden;
    }
    .wrapper-container{
        min-height: 200px;
        background: white;
        width: 90%;
        margin: 30px auto 5px;
        border-radius: 6px;
    }
    .left-menu{
        padding: 6px 0;
    }
</style>
<template>
    <div class="layout">
        <div class="wrapper-container">
            <Row>
                <Col span="4" class="left-menu">
                <Menu theme="light" :activeName="activeKey" @on-select="select">
                    <Menu-group v-for="sy_menu in menus" :title="sy_menu.name">
                        <Menu-item v-for="sy_it in sy_menu.children" :name="sy_it.opname">
                            <Icon :type="sy_it.icon"></Icon>&nbsp;{{sy_it.name}}
                        </Menu-item>
                    </Menu-group>
                </Menu>
                </Col>
                <Col span="20">
                    <router-view></router-view>
                </Col>
            </Row>
        </div>
    </div>
</template>
<script>
    export default {
        data(){
            return {
                activeKey    : '',
                menus        : []
            };
        },
        created() {
            // 获取菜单
            let that = this;

            axios.post("/admin/menu/menus.html").then(function (res) {
                that.menus = res.data;
            }).finally(function (w) {
                that.activeKey = that.$route.name;
            });
        },
        methods: {
            handleStart () {
                this.$Modal.info({
                    title: '温馨提示',
                    content: '功能待完善,敬请期待!'
                });
            },
            select(n){
                this.$router.push({name:n});
            }
        }
    }
</script>

行文仓促,如果有问题,欢迎交流。

展开阅读全文
打赏
0
0 收藏
分享
加载中
你只需要 this.$nextTick就能解决
2018/06/07 15:11
回复
举报
你只需要 this.$nextTick就能解决
2018/06/07 15:11
回复
举报
你只需要 this.$nextTick就能解决
2018/06/07 15:11
回复
举报
更多评论
打赏
3 评论
0 收藏
0
分享
返回顶部
顶部