You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3 CoreUI Admin模板菜单图标点击报错求助

CoreUI Vue Admin侧边栏折叠功能失效问题解决

问题描述

安装CoreUI Vue Admin模板后,其他功能正常,仅点击侧边栏菜单图标触发折叠功能时失效,控制台抛出以下错误:

  • [vuex] unknown mutation type: updateSidebarVisible main.js:17
  • vuex.esm-bundler.js:943 [vuex] unknown mutation type: toggleSidebar

相关代码文件

AppHeader.vue

<template>
  <CHeader position="sticky" class="mb-4">
    <!--  eslint-disable  -->
        <CContainer fluid>
            <!-- <CHeaderToggler class="ps-1" @click="$store.commit('toggleSidebar')">
   <CIcon icon="cil-menu" size="lg" />
            </CHeaderToggler> -->
             <CHeaderToggler class="ps-1" @click="toggleSidebar">
   <CIcon icon="cil-menu" size="lg" />
            </CHeaderToggler>
            <CHeaderBrand class="mx-auto d-lg-none" to="/">
                <CIcon :icon="logo" height="48" alt="Logo" />
            </CHeaderBrand>
            <CHeaderNav class="d-none d-md-flex me-auto">
                <CNavItem>
                    <CNavLink href="/dashboard"> Dashboard </CNavLink>
                </CNavItem>
                <!-- <CNavItem>
                                          <CNavLink href="">Users</CNavLink>
                                        </CNavItem>
                                        <CNavItem>
                                          <CNavLink href="">Settings</CNavLink>
                                        </CNavItem> -->
            </CHeaderNav>
            <CHeaderNav>
                <CNavItem>
                    <CNavLink href="">
                        <CIcon class="mx-2" icon="cil-bell" size="lg" />
                    </CNavLink>
                </CNavItem>
                <CNavItem>
                    <CNavLink href="">
                        <CIcon class="mx-2" icon="cil-list" size="lg" />
                    </CNavLink>
                </CNavItem>
                <CNavItem>
                    <CNavLink href="">
                        <CIcon class="mx-2" icon="cil-envelope-open" size="lg" />
                    </CNavLink>
                </CNavItem>
                <AppHeaderDropdownAccnt />
            </CHeaderNav>
        </CContainer>
        <CHeaderDivider />
        <CContainer fluid>
            <AppBreadcrumb />
        </CContainer>
    </CHeader>
</template>

<script>
/*  eslint-disable */
import { mapMutations } from 'vuex';
import AppBreadcrumb from './AppBreadcrumb'
import AppHeaderDropdownAccnt from './AppHeaderDropdownAccnt'
import { logo } from '@/assets/brand/logo'

export default {
    name: 'AppHeader',
    components: {
        AppBreadcrumb,
        AppHeaderDropdownAccnt,
    },
    methods: {
    ...mapMutations(['toggleSidebar']),
    },
    setup() {
        return {
            logo,
        }
    },
}
/*  eslint-disable */
</script>

store/index.js

import { createStore } from 'vuex'

export default createStore({
  state: {
    sidebarVisible: '',
    sidebarUnfoldable: false,
  },
  mutations: {
    toggleSidebar(state) {
      state.sidebarVisible = !state.sidebarVisible
    },
    toggleUnfoldable(state) {
      state.sidebarUnfoldable = !state.sidebarUnfoldable
    },
    updateSidebarVisible(state, payload) {
      state.sidebarVisible = payload.value
    },
  },
  actions: {},
  modules: {},
})

main.js

// eslint-disable-next-line
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import auth from './auth/auth'
import axios from 'axios'

import CoreuiVue from '@coreui/vue'
import CIcon from '@coreui/icons-vue'
import { iconsSet as icons } from '@/assets/icons'
import DocsExample from '@/components/DocsExample'

const app = createApp(App)
// app.use(store)
app.use(router)
app.use(CoreuiVue)

app.provide('icons', icons)
app.component('CIcon', CIcon)
app.component('DocsExample', DocsExample)

// Access token code
axios.defaults.baseURL = 'https://your-instance.salesforce.com'

axios.interceptors.request.use((config) => {
  const accessToken = auth.getters.accessToken
  if (accessToken) {
    config.headers.Authorization = `Bearer ${accessToken}`
  }
  return config
})

axios.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response.status === 401) {
      // Access token has expired, redirect to the login page.
      // You can also show a message to the user indicating that they need to log in again.
      // Replace '/login' with the actual path to your login page.
      window.location.href = '/login'
    }
    return Promise.reject(error)
  },
)
app.use(store)
app.use(auth)
app.mount('#app')

问题定位

  1. Store注册顺序错误:在main.js中,app.use(store)被放在router、CoreUI插件之后,甚至在axios拦截器配置之后才注册。Vue 3中,store需要尽早注册,确保组件(包括CoreUI内部组件)初始化时能访问到store实例,否则会导致调用mutation时找不到对应的store。
  2. Options API与Composition API混用冲突:AppHeader.vue中同时使用了Options API的mapMutations和Composition API的setup,虽然Vue 3允许混用,但可能导致方法映射出现异常。

解决方法

方法一:调整Store注册顺序

修改main.js,将app.use(store)放在所有插件注册的最前面:

const app = createApp(App)
app.use(store) // 优先注册store
app.use(router)
app.use(CoreuiVue)

// ...后续其他代码保持不变
app.use(auth)
app.mount('#app')

方法二:改用Composition API调用Mutation(推荐)

修改AppHeader.vue的script部分,使用Vue 3的Composition API直接调用store mutation,避免Options与Composition混用:

<script>
/*  eslint-disable */
import { useStore } from 'vuex';
import AppBreadcrumb from './AppBreadcrumb'
import AppHeaderDropdownAccnt from './AppHeaderDropdownAccnt'
import { logo } from '@/assets/brand/logo'

export default {
    name: 'AppHeader',
    components: {
        AppBreadcrumb,
        AppHeaderDropdownAccnt,
    },
    setup() {
        const store = useStore();
        // 定义toggleSidebar方法直接调用store mutation
        const toggleSidebar = () => {
            store.commit('toggleSidebar');
        };
        return {
            logo,
            toggleSidebar
        }
    },
}
/*  eslint-disable */
</script>

验证

修改后重新启动项目,点击侧边栏菜单图标,即可正常触发折叠功能,控制台不再抛出错误。

内容的提问来源于stack exchange,提问作者Ali Hassan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:24:51