DWQA QuestionsCategory: ProgramIView dynamically sets the menu component open names, but it doesn't work. How to solve this problem?
Awbeci asked 2 months ago

I set open names dynamically in my code, but it doesn’t work?
For example: store.js

{
    state:{
        menu:{
            activeName:'4-1',
            openNames:['4']
        }
    }
}

MyComponents.vue


<Menu 
         
        theme="dark" 
        :active-name="menu.activeName" 
        :open-names="menu.openNames"
        @on-select="onSelect">
            <template v-for="menu in menu.list">
                <MenuItem v-if="!menu.children" :name="menu.id" :key="menu.id">
                    <Icon :type="menu.icon" :key="menu.id"></Icon>
                    <span class="layout-text" :key="menu.id">{{menu.name}}</span>
                </MenuItem>
                <Submenu v-if="menu.children" :name="menu.id" :key="menu.id">
                    <template slot="title">
                        <Icon :type="menu.icon"></Icon>
                        <span class="layout-text">{{ menu.name }}</span>
                    </template>
                    <template v-for="child in menu.children">
                        <MenuItem :name="`${menu.id}-${child.id}`" :key="child.id">
                            <Icon :type="child.icon" :key="child.id"></Icon>
                            <span class="layout-text" :key="child.id">{{ child.name }}</span>
                        </MenuItem>
                    </template>
                </Submenu>
            </template>
        </Menu>
        import { mapState,mapActions } from 'vuex'

    export default {
        components:{
            Bottom
        },
        data(){
            return{
                
            }
        },
        computed:{
            ...mapState([
                'logo',
                'menu',
                'breadcrumbs',
                'tags'
            ])
        },
5 Answers
Best Answer
Awbeci answered 2 months ago

Solved. With JS Cookie:

<Menu 
        ref="side_menu"
        theme="dark" 
        :active-name="activeName" 
        :open-names="openNames"
        @on-select="onSelect"
        @on-open-change="onOpenChange">
            <template v-for="menu in menu">
                <MenuItem v-if="!menu.children" :name="menu.id" :key="menu.id">
                    <Icon :type="menu.icon" :key="menu.id"></Icon>
                    <span class="layout-text" :key="menu.id">{{menu.name}}</span>
                </MenuItem>
                <Submenu v-if="menu.children && menu.children.length>=1" :name="menu.id" :key="menu.id">
                    <template slot="title">
                        <Icon :type="menu.icon"></Icon>
                        <span class="layout-text">{{ menu.name }}</span>
                    </template>
                    <template v-for="child in menu.children">
                        <MenuItem :name="`${menu.id}-${child.id}`" :key="child.id">
                            <Icon :type="child.icon" :key="child.id"></Icon>
                            <span class="layout-text" :key="child.id">{{ child.name }}</span>
                        </MenuItem>
                    </template>
                </Submenu>
            </template>
        </Menu>
mounted(){
            let open_names = Cookies.getJSON('menu_opennames');
            let active_name = Cookies.getJSON('active_name');
            if(open_names || active_name){
                this.openNames = open_names || [];
                this.activeName = active_name || 0;
                this.$nextTick(()=>{
                    this.$refs.side_menu.updateOpened();
                    this.$refs.side_menu.updateActiveName()
                })
            }
        },
        methods:{
            onOpenChange(name){
                //Set the array name of menu expansion submenu
                Cookies.set('menu_opennames',name);
            },
            onSelect(name){        
                //Set the name of menu activation        
                Cookies.set('active_name',name);
Small white sand at the front replied 2 months ago

It is solved that the data type of the value in opennames array and the value of activename should be consistent. Otherwise, it can be highlighted, but it cannot be expanded automatically

ao_si_luo_ma_li answered 2 months ago

After setting the opennames and activename values, you need to call the following DOM methods to update after mounted. To be honest, these two methods are used only after reading the reply

<Menu ref="side_menu"></Menu>
this.$nextTick(() => {
  this.$refs.side_menu.updateOpened();
  this.$refs.side_menu.updateActiveName();
})

PS, opennames and activename cannot be assigned in $nexttick, otherwise the DOM update method will be invalid

seven_tao answered 2 months ago

Array received by open names, seeFile

Whisper answered 2 months ago

Opennames: 4 to opennames: [‘4 ‘]

Maple answered 2 months ago

I still don’t understand. Let me ask opennames how to operate. What format of JSON is needed