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

Vue复杂应用组件显隐切换实现方法(笔记应用场景)

Hey there! Since you're a Vue newbie working on your notes app and learning Vuex, let's walk through exactly how to toggle between your NotesList and MessagesList components when clicking that "Messages" button. This is a super common UI pattern, so once you get the hang of it, it'll feel second nature!

基础实现(本地组件状态)

If you just want to get the toggle working first without diving into Vuex, you can start with local state in the parent component (like your main App component or the component holding the toolbar):

  1. Define a reactive state property to track which view is active
  2. Use v-if (or v-show if you prefer toggling visibility instead of mounting/unmounting) to control which component renders
  3. Add a click handler to your "Messages" button to switch the active view

Here's a quick example with Vue 2's Options API:

<template>
  <div class="app-wrapper">
    <!-- Toolbar with your buttons -->
    <div class="toolbar">
      <button @click="switchToNotes">笔记</button>
      <button @click="switchToMessages">消息</button>
    </div>

    <!-- Conditionally render components -->
    <NotesList v-if="activeView === 'notes'" />
    <MessagesList v-if="activeView === 'messages'" />
  </div>
</template>

<script>
import NotesList from './components/NotesList.vue'
import MessagesList from './components/MessagesList.vue'

export default {
  components: { NotesList, MessagesList },
  data() {
    return {
      activeView: 'notes' // Start with notes visible by default
    }
  },
  methods: {
    switchToNotes() {
      this.activeView = 'notes'
    },
    switchToMessages() {
      this.activeView = 'messages'
    }
  }
}
</script>

结合Vuex的全局状态管理

Since you're learning Vuex, let's adapt this to use global state—this is great if you need to access the active view state from other components later on:

Step 1: Update your Vuex Store

Add a state property, mutation, and optional action to manage the active view:

// store/index.js
import { createStore } from 'vuex'

export default createStore({
  state: {
    activeView: 'notes' // Default view
  },
  mutations: {
    // Mutations are for sync state updates
    SET_ACTIVE_VIEW(state, viewName) {
      state.activeView = viewName
    }
  },
  actions: {
    // Actions are for async operations (optional here, but good practice)
    setActiveView({ commit }, viewName) {
      commit('SET_ACTIVE_VIEW', viewName)
    }
  },
  getters: {
    // Optional: Getter to access the state cleanly
    activeView: state => state.activeView
  }
})

Step 2: Use Vuex in Your Parent Component

Vue 2 Options API:

<template>
  <div class="app-wrapper">
    <div class="toolbar">
      <button @click="setActiveView('notes')">笔记</button>
      <button @click="setActiveView('messages')">消息</button>
    </div>

    <NotesList v-if="activeView === 'notes'" />
    <MessagesList v-if="activeView === 'messages'" />
  </div>
</template>

<script>
import NotesList from './components/NotesList.vue'
import MessagesList from './components/MessagesList.vue'
import { mapState, mapActions } from 'vuex'

export default {
  components: { NotesList, MessagesList },
  computed: {
    // Map the Vuex state to a local computed property
    ...mapState(['activeView'])
  },
  methods: {
    // Map the Vuex action to a local method
    ...mapActions(['setActiveView'])
  }
}
</script>

Vue 3 Composition API:

<template>
  <div class="app-wrapper">
    <div class="toolbar">
      <button @click="updateActiveView('notes')">笔记</button>
      <button @click="updateActiveView('messages')">消息</button>
    </div>

    <NotesList v-if="activeView === 'notes'" />
    <MessagesList v-if="activeView === 'messages'" />
  </div>
</template>

<script setup>
import NotesList from './components/NotesList.vue'
import MessagesList from './components/MessagesList.vue'
import { useStore } from 'vuex'
import { computed } from 'vue'

const store = useStore()
// Access the Vuex state via a computed property
const activeView = computed(() => store.state.activeView)

const updateActiveView = (viewName) => {
  // Dispatch the action (or commit the mutation directly if no async work)
  store.dispatch('setActiveView', viewName)
}
</script>

更简洁的动态组件方式

If you want to clean up your template a bit, you can use Vue's <component :is="..."> syntax to dynamically render the active component:

<template>
  <div class="app-wrapper">
    <div class="toolbar">
      <button @click="updateActiveView('notes')">笔记</button>
      <button @click="updateActiveView('messages')">消息</button>
    </div>

    <!-- Dynamically render the correct component -->
    <component :is="currentComponent" />
  </div>
</template>

<script setup>
import NotesList from './components/NotesList.vue'
import MessagesList from './components/MessagesList.vue'
import { useStore } from 'vuex'
import { computed } from 'vue'

const store = useStore()
const activeView = computed(() => store.state.activeView)

// Map the active view string to the actual component
const currentComponent = computed(() => {
  return activeView.value === 'notes' ? NotesList : MessagesList
})

const updateActiveView = (viewName) => {
  store.commit('SET_ACTIVE_VIEW', viewName)
}
</script>

Quick Notes:

  • Use v-if if you want the component to be mounted/unmounted when toggling (good for performance if components are heavy)
  • Use v-show if you just want to toggle visibility (components stay mounted, better for frequent toggles)
  • Vuex is useful here if you need to share the active view state across multiple components—if it's only needed in this one parent/child setup, local state works just fine!

内容的提问来源于stack exchange,提问作者Rasim AVCI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:08:06