Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is v-show not working on static elements?

I am not a web developer and this is the first time I play with a web framework – so please go easy on me. The framework I’m trying to learn is vue.js. Version 3.

What I try to achieve:

  • 4 app instances. (nav, defaultApp, bootstrapApp, vueApp).
  • Depending on the navbar item I select, one of the 3 other apps should show. The others shall hide.

I looked at various places on the internet about how to do it and added console.log() output, which convinces me, that the calls actually happen as I think they should.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I am aware, that there are alternatives, but the v-show approach seems most readable to me.

What is not working:

  • The 3 apps are visible all the time and never get hidden.

It is probably a very silly mistake on my part. Who can spot it?

<!DOCTYPE html>
<html>
  <head>
    <title>Learning web framworks</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" 
          rel="stylesheet" 
          integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" 
          crossorigin="anonymous"/>
    <!-- TODO: Make sure to use the production build (*.prod.js) when deploying for production.<!-->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  </head>
  <body>
    <nav id="navbar" class="navbar navbar-dark navbar-expand-lg bg-dark">
      <div class="container-fluid">
        <a @click.prevent="showDefault" class="navbar-brand" href="#">Navbar</a>
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item">
            <a @click.prevent="showBootstrap" class="nav-link" href="#">Bootstrap</a>
          </li>
          <li class="nav-item">
            <a @click.prevent="showVue" class="nav-link" href="#">Vue.js</a>
          </li>
        </ul>
      </div>
    </nav>
    <div v-show="isShow" id="default-content">
      <p>default content</p>
    </div>
    <div v-show="isShow" id="bootstrap-content">
      <p>bootstrap content</p>
    </div>
    <div v-show="isShow"
          id="vue-content">
      <p>vue content</p>
    </div>

    <script 
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" 
      integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" 
      crossorigin="anonymous"></script>

    <script>
      const { createApp } = Vue

      let defaultApp = createApp({
        data() {
          return {
            isShow: true,
          }
        },
        watch: {
          isShow(val,oldVal) {
            console.log(`defaultApp.isShow( ${oldVal} -> ${val} )`);
          }
        }
      }).mount("#default-content");
      let bootstrapApp = createApp({
        data() {
          return {
            isShow: false,
          }
        },
        watch: {
          isShow(val,oldVal) {
            console.log(`bootstrapApp.isShow( ${oldVal} -> ${val} )`);
          }
        }
      }).mount("#bootstrap-content");
      let vueApp = createApp({
        data() {
          return {
            isShow: false,
          }
        },
        watch: {
          isShow(val,oldVal) {
            console.log(`vueApp.isShow( ${oldVal} -> ${val} )`);
          }
        }
      }).mount("#vue-content");

      let nav = createApp({
        data() {
          return {
            // pages: [
            //   { title: "Navbar", url: "#default-content" },
            //   { title: "Bootstrap", url: "#bootstrap-content" },
            //   { title: "Vue.js", url: "#vue-content" },
            // ],
          };
        },
        methods: {
          showDefault: function() {
            console.log("showDefault()");
            defaultApp.$data.isShow = true;
            bootstrapApp.$data.isShow = false;
            vueApp.$data.isShow = false;
          },
          showBootstrap: function() {
            console.log("showBootstrap()");
            defaultApp.$data.isShow = false;
            bootstrapApp.$data.isShow = true;
            vueApp.$data.isShow = false;
          },
          showVue: function () {
            console.log("showVue()");
            defaultApp.$data.isShow = false;
            bootstrapApp.$data.isShow = false;
            vueApp.$data.isShow = true;
          }

        }
      }).mount('#navbar');
    </script>
  </body>
</html>

>Solution :

Don’t use v-show on the root element of the apps – probably treat the root element as not being part of the "vue" App at all, it’s just a container for the App

Instead, use it on the content

In your example, just the <p> but you may want to wrap actual content in a div or appropriate

const { createApp } = Vue;

let defaultApp = createApp({
    data() {
        return {
            isShow: true,
        };
    },
    watch: {
        isShow(val, oldVal) {
            console.log(`defaultApp.isShow( ${oldVal} -> ${val} )`);
        },
    },
}).mount("#default-content");
let bootstrapApp = createApp({
    data() {
        return {
            isShow: false,
        };
    },
    watch: {
        isShow(val, oldVal) {
            console.log(`bootstrapApp.isShow( ${oldVal} -> ${val} )`);
        },
    },
}).mount("#bootstrap-content");
let vueApp = createApp({
    data() {
        return {
            isShow: false,
        };
    },
    watch: {
        isShow(val, oldVal) {
            console.log(`vueApp.isShow( ${oldVal} -> ${val} )`);
        },
    },
}).mount("#vue-content");

let nav = createApp({
    data() {
        return {
        };
    },
    methods: {
        showDefault: function () {
            console.log("showDefault()");
            defaultApp.$data.isShow = true;
            bootstrapApp.$data.isShow = false;
            vueApp.$data.isShow = false;
        },
        showBootstrap: function () {
            console.log("showBootstrap()");
            defaultApp.$data.isShow = false;
            bootstrapApp.$data.isShow = true;
            vueApp.$data.isShow = false;
        },
        showVue: function () {
            console.log("showVue()");
            defaultApp.$data.isShow = false;
            bootstrapApp.$data.isShow = false;
            vueApp.$data.isShow = true;
        },
    },
}).mount("#navbar");
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous" />
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<nav id="navbar" class="navbar navbar-dark navbar-expand-lg bg-dark">
  <div class="container-fluid">
    <a @click.prevent="showDefault" class="navbar-brand" href="#">Navbar</a>
    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
      <li class="nav-item">
        <a @click.prevent="showBootstrap" class="nav-link" href="#">Bootstrap</a>
      </li>
      <li class="nav-item">
        <a @click.prevent="showVue" class="nav-link" href="#">Vue.js</a>
      </li>
    </ul>
  </div>
</nav>
<div id="default-content">
  <p v-show="isShow">default content</p>
</div>
<div id="bootstrap-content">
  <p v-show="isShow">bootstrap content</p>
</div>
<div id="vue-content">
  <p v-show="isShow">vue content</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading