Is it possible to render conditional templates using props in Vue3?

I'm attempting to create a toggle button that opens a hamburger menu when clicked.

I created the boolean property "clicked" in the file "App.vue", passed it down to "Navbar.vue", and now I want to be able to toggle the "clicked" property to either "true" or "false" by clicking in the navbar, in order to show or hide the backdrop and drawer.

I attempted to use an "emit" function, which seems to be working, but the template is not responding to the "clicked" variable and is still showing even when it should be hidden (when false).

In the code provided below, where did I make a mistake? How do you implement conditional rendering with props? Can anyone offer assistance?


App.vue

<template>
  <NavBar :clicked="clicked" @toggleDrawer="toggleMenu()" />
  <BackDrop :clicked="clicked" />
  <SideDrawer :clicked="clicked" />
  <router-view></router-view>
</template>

<script>
export default {
  name: "App",
  components: { NavBar, BackDrop, SideDrawer },

  setup() {
    const clicked = ref(false);

    const toggleMenu = () => {
      clicked.value = !clicked.value;
    };
    return { clicked, toggleMenu };
  },
};
</script>

NavBar.vue

<template>
  <nav class="navbar">
  /* MORE CODE */
    <div class="hamburger_menu" @click="toggleEvent">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </nav>
</template>

<script setup>
import { defineEmits, defineProps } from "vue";

const props = defineProps({
  clicked: Boolean,
});

const emit = defineEmits(["toggleDrawer"]);

const toggleEvent = () => {
  console.log("toggleEvent running");
  emit("toggleDrawer", !props.clicked);
};
</script>

Backdrop.vue

<template v-if="props.clicked">
  <div class="backdrop"></div>
</template>

<script setup>
import { defineProps } from "vue";
// eslint-disable-next-line no-unused-vars
const props = defineProps({
  clicked: Boolean,
});
</script>

SideDrawer.vue

<template v-if="props.clicked">
  <div class="sidedrawer"></div>
</template>
<script setup>
import { defineProps } from "vue";
const props = defineProps({
  clicked: Boolean,
});
</script>

Am I passing the prop incorrectly? Is "props.clicked" not functioning in "v-if" directives or templates? How should I incorporate the "v-if" directive with the "clicked" property I have?

Answer №1

In accordance with @neha-soni's advice,

Upon execution of the code, everything is in proper working order

Vue strongly suggests utilizing kebab-cased event listeners within templates. Your toggleDrawer will automatically be converted to kebab case when utilized in the parent component. Therefore, in app.vue, you can use it as @toggle-drawer,

 <NavBar :clicked="clicked" @toggle-drawer="toggleMenu()" />

Referencing the Vue documentation here

Event names undergo automatic case transformation. It should be noted that a camelCase event was emitted, but can be listened for using a kebab-cased listener in the parent component. Similar to prop casing, the usage of kebab-cased event listeners in templates is recommended.

Answer №2

Upon executing the code, it appears to be functioning correctly. I have a couple of suggestions to enhance clarity by eliminating unnecessary code, which may cause confusion until the desired outcome is achieved.

  1. Considering props are immutable (read-only) in the child component, there seems to be no purpose in returning the props value back to the parent through
    emit("toggleDrawer", !props.clicked)
    , as the parent component already retains the original status.
  2. Furthermore, though you pass props data during the event using
    emit("toggleDrawer", !props.clicked)
    , it remains unused when invoking the function
    @toggleDrawer="toggleMenu()"
    in App.vue. Hence, it would be advisable to remove this redundant data-passing segment.
  3. The property clicked undergoes updates within both the parent (App.vue) and child components. By simply console logging and displaying the clicked property in the child and parent templates like so: {{ clicked }} at the beginning, you can observe the refreshed status.
const toggleMenu = () => {
  console.log('Before______', clicked.value)
  clicked.value = !clicked.value;
  console.log('After______', clicked.value)
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

An issue has been identified with the functionality of an Ajax request within a partial view that is loaded through another Ajax request specifically in

Here is the current scenario within my ASP.NET MVC application: The parent page consists of 3 tabs, and the following javascript code has been implemented to handle the click events for each tab: Each function triggers a controller action (specified in t ...

Execute a jQuery function only after a form has been submitted for the first time

In the same webpage, I have three lists in HTML format. Whenever an option is selected from the first list, it triggers the population of the second list based on the selection. Similarly, the third list is populated based on the selection from the second ...

during implementation of ng-repeat directive with JSON dataset

When I receive JSON data and attempt to display it using the ng-repeat directive, I encounter an error ng-dupes error <table> <tr ng-repeat="emp in empArr"> <td>{{emp.empcode}}</td> <td>{{emp.empName}}< ...

Handling events sequentially in RxJS

Currently, I am utilizing RxJS to handle a stream of events. The processing code at the end is quite resource-intensive, such as loading a file, performing tasks, and storing data in a database. const rx = require("rxjs") // simulating numerous ...

Is there a way to work around the CORS policy in order to fetch data from URLs?

I have been developing a tool that can analyze URLs from an uploaded CSV file, search the text content of each URL, and calculate the total word count as well as the occurrences of "saas" or "software". The goal is to generate a new CSV file with the origi ...

There seems to be a JSON syntax error on the website for tracking Covid-

Hi everyone, I'm currently working on a Covid-19 tracker website and facing an issue that says: 'SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data' ; Being new to web development, I am unsure about what&apo ...

Using the .map function on JSON data with and without a parent element in JavaScript

In my current project, I am working on a React + Rails application. For handling JSON data, I typically use the default jbuilder in Rails. However, following the recommendations from the react-rails official documentation, I started adding a root node to m ...

What is the best way to utilize toggle("slide") in order to reveal a message letter by letter?

I am currently experimenting with the `.toggle("slide") function to create an effect where a piece of text appears as though each letter is sliding in. However, I've noticed that instead of a smooth slide, it looks more like the text is flying in abru ...

Error during live-server npm installation: symlink issue persists even with root/admin privileges

In my current project, I am following a tutorial on AngularJS from the book titled "Unraveling AngularJS 1.5 (With Over 130 Complete Samples" by István Novák, which stipulates the need for installation of Node.js. The appendix of this book provides comma ...

The case of ASP.NET MVC Form Triggering Duplicate Submissions

Currently, I have a straightforward form that contains a few questions. To ensure that the inputs are filled before the form is submitted, I am utilizing the validator.min.js library from here. The structure of my form is as follows: @using (Html.BeginFo ...

html table displaying incorrect data while using dynamic data in vue 3

example status 1 Hello there! I'm trying to create a table (check out example status 1 for guidance). Here's the code snippet I am using: <table> <tr> <th>Product</th> <th>Price</th> <th>Av ...

Tips for deactivating trackball rotation events and triggering a custom rotation event while adjusting the rotation speed within the custom event

In an attempt to disable the trackball control rotate event and trigger a custom rotate event, I have encountered some challenges. While setting controls.enableRotate = false; works for OrbitControl, it does not completely disable the trackball control r ...

Enhancing Angular 4 classes with dependency injection techniques

Currently utilizing angular 4 and angular cli for my project development. I have created some classes that serve as the base for my components! However, as the constructors of these classes grow during development, I find myself in a phase where I need to ...

Is it possible to have a stripped-down version of Saleor without any frontend frameworks, similar to a more basic setup?

Considering using Saleor for a specialized "single-type-product" online store. After installing Saleor, I noticed that it comes with a large requirements file that includes react.js and numerous other frontend components. I am not interested in these add ...

On mobile, three divisions that are initially set to occupy 33.33% of the width each will expand to 100

I have a good handle on accomplishing this using JavaScript, but I'm now curious if there is some clever CSS trick that can achieve the same result. My goal is to have each div take up the entire screen when viewed on a mobile device. Below is what it ...

Creating a Deployment of Vue.js Application with Express and MongoDB on Heroku

I've been grappling with this issue for two days now and can't seem to crack it. My goal is to deploy a Vue front end and an express back end app to Heroku. Within my root directory, I have a "public" folder housing the front end code and a "ser ...

Can variable values be utilized as a union type within Typescript?

I'm attempting to achieve a setup similar to the following example using Typescript: const fruitApple:string = 'Apple'; const fruitOrange:string = 'Orange'; export type FruitOptions = fruitApple | fruitOrange //the compiler doe ...

steps to iterate through an array or object in javascript

Hello, I am facing an issue while trying to loop through an array or object. Can someone help me out? Are arrays and objects different when it comes to using foreach? function fetchData() { fetch("https://covid-193.p.rapidapi.com/statistics", { ...

What is the functionality behind utilizing "import * as bootstrap from '../node_modules/bootstrap"?

At the beginning of my app.js file, I include the line import * as bootstrap from '../../node_modules/bootstrap'; After calling console.log(bootstrap) on the following line, I can confirm that the bootstrap variable contains an object resembling ...

Switching from using v-data-table to v-virtual-scroll

I am currently in the process of switching from using v-data-table to v-virtual-scroll, but I am struggling to determine the correct syntax for the virtual scroller. Can you assist me with this, please? I want to maintain the same display as before, but no ...