Home » vue » How to open open a side panel upon a button press using vue.js?

How to open open a side panel upon a button press using vue.js?

Posted by: admin November 26, 2021 Leave a comment

Questions:

I’m developing my first app with Vue and need some advice with trying to open a panel upon pressing a button in the header.

I’m starting with a basic HTML template, trying to add interactivity after pressing a button that’s contained in the header.

When pressing the button, I’m getting the following message in the console:

vue.js:597 [Vue warn]: Invalid handler for event “click”: got
undefined

(found in )

The code I’m using is as follows:

HTML:

<!-- Doctype HTML5 -->
<!DOCTYPE html>
<html lang="en" />

<head>

  <link rel="stylesheet" href="css/normalize.css">

  {{ $style := resources.Get "scss/main.scss" | toCSS | minify | fingerprint }}
  <link rel="stylesheet" href="{{ $style.Permalink }}">

  <script src="js/vue.js"></script>

  <script type="text/javascript" src="js/vue-proj-info.js"></script>

</head>

<body>
      <header>

      <div class="h-branding">
        <div id="h-nLogo">
          <img src="img/med-logo-rev.png"height="70" />
        </div>
        <div id="h-title">
          <h1>Executive Blueprint</h1>
          <p class="subheader"><span class="tr-tier">Tier 1</span> - <span class="tr-service">Executive</span></p>
        </div>
      </div>

      <div id="h-toggles">
        <div class="buttonGroup">
          <button type="" name="tier1">Tier 1</button>
          <button type="" name="tier2">Tier 2</button>
          <button type="" name="tier3">Tier 3</button>
        </div>
        <div class="buttonGroup">
          <button type="" name="executive">Executive</button>
          <button type="" name="concierge">Concierge</button>
        </div>

          </div>

  <proj-slideout ref="proj-slideout" id="proj-slideout" :class="{ isOpen: isOpen }">></proj-slideout>


      <div id="h-infoButton">
        <div class="buttonGroup">
          <button type="button" name="projInfo" class="proj-slideout-opener"
             @click="open">Project Information</button>
        </div>
      </div>

      </header>

JS:

    Vue.component('proj-slideout', {
  template: '#proj-slideout',
  props: ['show'],
  data: () => ({
    isOpen: false,
    projContent: 'overview' /* overview, jtbd, tiers, files */
  }),
  methods: {
    close() {
      this.isOpen = false;
    },
    open() {
      this.isOpen = true;
      console.log('Open Panel');
    }
  }
});

document.addEventListener("DOMContentLoaded", function(event) {
  var app = new Vue({
    el: 'header'
  })
});

SCSS:

#proj-slideout {
  position: fixed;
  top: 0;
  right: 0;
  width: 90vw;
  height: 100vh;
  padding: 30px;
  display: flex;
  flex-direction: row;
  background-color: white;
  transform: translateX(-100%);
  transition: transform 0.6s ease(out-cubic);
  display: none;

  &.isOpen {
    transform: translateX(0);
  }

Any advice would be helpful!

Answers:

In your code, @click="open" is refer to Vue parent component scope, so you should define isOpen and open in parent Vue component

document.addEventListener("DOMContentLoaded", function(event) {
  var app = new Vue({
    el: 'header',
    data: () => ({
      isOpen: false,
    }),
    methods: {
      close() {
        this.isOpen = false;
      },
      open() {
        this.isOpen = true;
        console.log('Open Panel');
      }
    }
  })
});

###

All you need is to use v-show

On the template In your component tag add v-if or v-show like so :

<projContent v-show="isOpen" ... />

On the trigger button use directly the click event to set isOpen to false or true like this :

<button @click="isOpen = !isOpen" ... >Project Information</button>//or even better @click="isOpen ^= 1"

Now when you click the button it will set isOpen to its opposite value, if it’s false it will become true and your projContent component will show up, if it’s true, it will be set to false, hiding automatically your component, you don’t even need to set a method to get the job done, it’s directly set in the event.

Don’t forget to remove display:none from your scss

If you need to add a transition animation here is the link “Vue transitions