简体   繁体   中英

Emit style value to parent on vuejs

I am fairly new to VueJS and trying to figure everything out.

I have a specific issue on my site where I have a TopBar component that contains the logo and the menu.

<template>
  <div id="topBar">
    <div class="container align-center justify-between">
      <router-link to="/">
        <img src="@/assets/logo-white.svg" alt="logo" />
      </router-link>
      <a href="#" @click="showMenu = !showMenu" class="menu-button">
        <img src="@/assets/menu-icon.svg" />
      </a>
    </div>

    <nav id="menu" class="flex align-center" v-bind:class="{ 'js-active': showMenu }">
      <ul id="topNav" class="list-unstyled">
        <li>
          <router-link to="/login">Login</router-link>
        </li>

        <li>
          <router-link to="/opret">Register</router-link>
        </li>

        <li>
          <a href="#" class="close-button" @click="showMenu = false">
            <svg width="20" height="20" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M2.76316 30.2368L30.4059 2.59409" stroke="white" stroke-width="3" stroke-linecap="square" />
              <path d="M30.2368 30.2368L2.59409 2.59409" stroke="white" stroke-width="3" stroke-linecap="square" />
            </svg>
          </a>
        </li>
      </ul>

      <div class="container">
        <ul class="list-unstyled">
          <li>
            <router-link to="/register">Register</router-link>
          </li>
          <li>
            <router-link to="/news">News</router-link>
          </li>
          <li>
            <router-link to="/about>About</router-link>
          </li>
        </ul>
      </div>
    </nav>
  </div>
</template>

<script>
import CloseMixin from "../mixins/close";

export default {
  mixins: [CloseMixin],
  data: function() {
    return {
      showMenu: false
    };
  },
  watch: {
    $route() {
      this.showMenu = false;
    }
  },
  methods: {
    close() {
      let nav = document.querySelector("#menu");

      if (nav.classList.contains("js-active")) {
        nav.classList.remove("js-active");
      }
    }
  },
  mounted() {}
};
</script>

And I am inserting this component in my App.vue view

<template>
  <div id="app">
    <TopBar></TopBar>
    <router-view></router-view>
    <Footer></Footer>
  </div>
</template>

My issue is that on some of my views the logo and colors has to be dark, because the view has a light background. So I somehow want to $emit a menuStyle to my TopBar parent component so that I can set a logo and color based on the menuStyle emitted from the child

So that I might end up with something like

<div id="topBar">
   <router-link to="/">
        <img src="@/assets/logo-dark.svg" alt="logo" v-if="menuStyle === 'dark' />
        <img src="@/assets/logo-white.svg" alt="logo" v-else />
     </router-link>
</div>

My main child view is this:

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

<script>
export default {
  name: "Profile",
};
</script>

You can emit the event from child router view to outer component, here is the trick

<template>
  <div id="app">
    <TopBar :menuStyle="menuStyleProp"></TopBar>
    <router-view @eventFromChild="updateMenuStyle"></router-view>
    <Footer></Fdooter>
  </div>
</template>

<script>
export.default {
name: 'main-component',
data() {
 return {
   menuStyleProp: "",
 };
},
methods: {
  updateMenuStyle(val) {
    this.menuStyleProp = val;
  }
}
}
</script>

F

rom the child you can just emit the event, so that router view listen to that event and update the props, top bar get updated with the new svg

In topbar component

<div id="topBar">
   <router-link to="/">
        <img src="@/assets/logo-dark.svg" alt="logo" v-if="menuStyle === 'dark' />
        <img src="@/assets/logo-white.svg" alt="logo" v-else />
     </router-link>
</div>

<script>
export default {
name: 'topbar-component',
props: {
  menuStyle: {
    type: String,
    default: "dark",
  }
 }
}
</script>

In the child component trigger an event to router view via

this.$router.app.$emit("eventFromChild", "dark") // change the value to dark or any

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM