Vue Component, switching state

Feeling like I'm losing it, this should be really simple but it's not working...

The idea is that when the link is clicked, the display property toggles between true and false. However, it's not working as expected.

Vue.component('dropdown', {
    props: [ 'expanded' ],
    data: function() {
      return {
        display: !!(this.expanded)
      }
    },
    template: '<div><transition name="expand"><slot :display="display"></slot></transition></div>'
  });
  window.app = new Vue({
   el: '#app'
  });
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
    <dropdown>
      <div slot-scope="{ display }">
        <a href="javascript:void(0)" @click="display = !display">Toggle {{ display }}</a>
        <div v-if="display">
          Dropdown content
        </div>
      </div>
  </dropdown>
</div>

Edit:

Updated code, I can't believe I missed that, I did in fact have the click event set to display = !display. But still, if you try clicking the button, you'll see that it doesn't change to true either...

Answer №1

After receiving a helpful comment from thanksd, I was able to update my solution even though I didn't fully grasp it at first.

The issue here is that within the slot, the reference to display pertains to an item in the scope-slot object. Modifying it there does not affect the original source variable. Instead, passing in and invoking a function will update the correct variable.

Vue.component('dropdown', {
  props: ['expanded'],
  data: function() {
    return {
      display: Boolean(this.expanded)
    }
  },
  methods: {
    toggle() {
        this.display = !this.display;
    }
  },
  template: '<div><transition name="expand"><slot :display="display" :toggle="toggle"></slot></transition></div>'
});

new Vue({
  el: '#app'
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <dropdown>
    <div slot-scope="{display, toggle}">
      <a href="javascript:void(0)" @click="toggle">Toggle {{ display }}</a>
      <div v-if="display">
        Dropdown content
      </div>
    </div>
  </dropdown>
</div>

Answer №2

One way to solve this issue is by introducing a custom v-model for the dropdown component, allowing a two-way binding of the display property with a property in its parent component. This eliminates the need to pass any data through the slot-scope.

Check out this example:

Vue.component('dropdown', {
  props: [ 'value' ],
  data() {
    return {
      display: !!(this.value)
    }
  },
  watch: {
    value(value) {
      this.$emit('input', value);
    }
  },
  template: '<div><transition name="expand"><slot></slot></transition></div>'
});

new Vue({
  el: '#app',
  data() {
    return { dropdownToggle: false }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
    <dropdown v-model="dropdownToggle">
      <div>
        <a href="javascript:void(0)" @click="dropdownToggle = !dropdownToggle">
          Toggle {{ dropdownToggle }}
        </a>
        <div v-if="dropdownToggle">
          Dropdown content
        </div>
      </div>
  </dropdown>
</div>

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

Is there a way to logout when the select event occurs using the key?

I am trying to figure out how to log out the key value when the select event is triggered. Specifically, I want to access the key={localState.id} within the <select></select> element in my HTML. This key value is crucial for a conditional stat ...

Loading content within the designated element

<div class="col-sm-6" id="ajaxform"></div> <!-- begin snippet: js hide: false --> <!-- language: lang-html --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <ul id="accordio ...

Learn how to use a function in Google Maps to calculate and display distances

I have a script obtained from this link here and I am trying to create a function that returns the distance. This is my current script: var calcRoute = function(origin, destination) { var dist; var directionsDisplay; var directionsService = ne ...

Leveraging python capabilities within html documents

English is not my first language, so please excuse any spelling errors. I am working on combining HTML and Python to develop a graphical user interface (GUI) that can communicate with a bus system (specifically KNX bus). Currently, I have a Raspberry Pi ...

Environment variables in Node process are uninitialized

I'm currently in the process of developing my first Express application, which requires interaction with an API using a secure API key. To ensure the security of this key and any future environment variables, I have decided to store them in a .env fil ...

How come the function is being triggered by my onclick button as soon as the page loads?

Currently, I am experiencing a challenge in my NodeJS project with Express. The issue lies with my EJS client side file when it comes to handling button click events. In my EJS file, I have imported a function from a JS file and can invoke it using <% ...

What causes the fixed div to appear when scrolling horizontally?

I have replicated this issue in a live example: http://jsfiddle.net/pda2yc6s When scrolling vertically, a specific div element sticks to the top. However, if the window is narrower than the wrapper's width and you scroll horizontally, the sticky elem ...

Unable to automatically prompt the button inside the iframe

In this scenario, an Iframe is automatically generated by a JavaScript script. I am looking to simulate a click by triggering a button, but unfortunately, it is not working as expected. You can view the code on JSFiddle. I have attempted various approache ...

Error in Mocha test: Import statement can only be used inside a module

I'm unsure if this issue is related to a TypeScript setting that needs adjustment or something else entirely. I have already reviewed the following resources, but they did not provide a solution for me: Mocha + TypeScript: Cannot use import statement ...

Is it illegal to escape quotes when using an image source attribute and onerror event in HTML: `<img src="x" onerror="alert("hello")" />`?

Experimenting with escape characters has been a fascinating experience for me. <img src="x" onerror=alert('hello'); /> <img src="x" onerror="alert(\"hello\")" /> The second code snippet triggers an illegal character error ...

Recursive array generation

Given an array 'featureList', the goal is to create a new array 'newArray' based on a specific ID. For example, for ID 5, the newArray would be ['MotherBoard','Antenna','Receiver'], where Receiver correspon ...

Leverage JavaScript Object Properties within Angular 5 Components

Here's a question I have on using ngx-charts in Angular 5. I am experimenting with ngx-charts to create a chart within my Angular 5 project. The code snippet for my component is shown below: import { Component, OnInit } from '@angular/core&ap ...

Differences between importing {fn1} from 'lib' and importing fn1 from 'lib'

When it comes to importing functions from lodash, I have been advised by my coworker that it is more efficient to import each function individually rather than as a group. The current method of importing: import {fn1, fn2, fn3} from 'lodash'; ...

Exploring the colors of legend navigation icons in Google Pie charts

Is there a way to customize the color of the navigation links in Google pie charts (specifically the blue text in the bottom right corner)? ...

Can a layer be sliced to create a text-shaped cutout?

I want to achieve a cool text effect where the background is visible through the letters. I have explored options with background images and colors, but I haven't found any examples where the underlying layer is revealed. Is this even possible? Imag ...

Semantic UI Troubles: Unraveling the Sidebars and #pusher Defects

Hey there, I could really use some assistance with an issue I'm facing. I have this particular structure that's causing me trouble. <div id="toolbar" class="toolbar overlay-displace-top clearfix toolbar-processed"> ... </div> < ...

Access the contents of objects during the creation process

I am currently in the process of creating a large object that includes API path variables. The challenge I am facing is the need to frequently modify these API paths for application migration purposes. To address this, I had the idea of consolidating base ...

Is it necessary to compile Jade templates only once?

I'm new to exploring jade in conjunction with express.js and I'm on a quest to fully understand jade. Here's my query: Express mentions caching jade in production - but how exactly does this process unfold? Given that the output is continge ...

Implement the color codes specified in the AngularJS file into the SASS file

Once the user logs in, I retrieve a color code that is stored in localstorage and use it throughout the application. However, the challenge lies in replacing this color code in the SASS file. $Primary-color:#491e6a; $Secondary-color:#e5673a; $button-color ...

Can a single file in NextJS 13 contain both client and server components?

I have a component in one of my page.tsx files in my NextJS 13 app that can be almost fully rendered on the server. The only client interactivity required is a button that calls useRouter.pop() when clicked. It seems like I have to create a new file with ...