使用导航栏组件中的按钮切换侧边栏组件

Toggle Sidebar component with button from Navbar Component

我正在尝试使用 Vuejs (v3) 学习 Laravel。 我有 3 个组件:App.vueNavbar.vueSidebar.vue

我想做的是,点击 sidebar-btn:

  1. 将变量 isSidebarActive 的值更改为 !isSidebarActive ---- 完成
  2. 更改class fontawesome(取决于isSidebarActive)。 ---- 完成
  3. 显示Sidebar.vue(取决于isSidebarActive

我尝试使用 props,但错误提示我无法更改值,所以我尝试使用 emits,但我似乎仍然无法正确设置。

app.js

require('./bootstrap');

import { createApp }    from 'vue'
import App              from './App.vue'
import router           from './routes'

// Partials
import Navbar           from './components/Navbar.vue'
import Sidebar          from './components/Sidebar.vue'

createApp(App)
.component('navbar', Navbar)
.component('sidebar', Sidebar)
.use(router)
.mount('#app')

App.vue

<template>
    <navbar></navbar>
    <sidebar v-bind:class="{ active: isSidebarActive }"></sidebar>

    <router-view></router-view>
</template>

<script>
export default {
    name: "App",
    data() {
        return {
            isSidebarActive: false,
        };
    },
}
</script>

Navbar.vue

<template>
<nav class="navbar navbar-expand-md navbar-dark bg-dark shadow-sm sticky-top">
    <div class="container">
        <div class="navbar-brand" >
            <span class="h4">
                Hello World!
            </span>

            <!-- Button to toggle Sidebar -->
            <span class="btn btn-outline-light btn-sm ms-2" id="sidebar-btn" style="border: 1px white" @click="toggleSidebar()">
                <i v-bind:class="[isSidebarActive ? 'fas fa-arrow-left' : 'fas fa-bars']" title="Sidebar Menu"></i>
            </span>
        </div>
    </div>
</nav>
</template>

<script>
export default {
    name: "Navbar",
    data() {
        return {
            isSidebarActive: false,
        };
    },
    emits: ['isSidebarActive'],
    methods: {
        toggleSidebar:function () {
            this.isSidebarActive = !this.isSidebarActive
            this.$emit("isSidebarActive", this.isSidebarActive)
        },
    },
}
</script>

请看下面的片段:

const app = Vue.createApp({
  data() {
    return {
      isSidebarActive: false,
    };
  },
  methods: {
    handleSidebar() { //  handle received event
      this.isSidebarActive = !this.isSidebarActive
    }
  }
})
app.component('Sidebar', {
  template: `<div>sidebar</div>`
})
app.component('Navbar', {
  template: `
     <div>Hello World!<button @click="toggleSidebar()">show/hide sidebar</button></div>
  `,
  methods: {
    toggleSidebar() {
      this.$emit("toggle") //  emit event
    },
  },
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3.2.29/dist/vue.global.prod.js"></script>
<div id="demo">
        <!--  listen to event from child, call method -->
  <navbar @toggle="handleSidebar"></navbar>
        <!--  conditionaly show/hide component -->
  <sidebar v-if="isSidebarActive"></sidebar>
</div>