2

Im kinda new to front end in general, especially vue.js. Im trying to make a small application that is going to contain 5 elements, each element is actually getting data from an object with 2 values - name and description. Also each object is in an array.

The name is by default displayed to block and the description by default displayed to none. I want the app to display the description to block whenever i click on the name. Here is the entire code, you can run it on codepen or locally, it will run without a problem. You can ignore everything above the body tag.

<html>
    <head>
        <style>
            *{margin: 0px; padding: 0px; font-family: sans-serif; list-style-type: none; }
            body{background: #003366;}
            #container{width: 1000px; margin: 100px auto;}
            #elements{width: 100%;}
            #elements li{display: inline-block; width: 40%; margin: 40px 5%; background: #FFF; color: #003366; box-shadow: 10px 10px 0px #222; user-select: none;}
            #elements li h1,h3{padding: 10px 20px;}
            #elements li h3{display: none;}
            #elements li h1{cursor: pointer;}
        </style>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    </head>
    <body>
        <div id="container">
            <ul id='elements'>
                <li v-for="eleObject in eleObjects">
                    <h1 v-on:click="expand" v-text="eleObject.name"></h1>
                    <h3 v-text="eleObject.description"></h3>
                </li>
            </ul>
        </div>
    </body>

    <script>
        let elementList = new Vue({
            el: "#elements",
            data:{
                eleObjects:[
                    {name: "HTML5", description: "Used for front end web development more specifically for building the structure of a website"},
                    {name: "CSS3", description: "Used for giving style to the HTML elements, their positioning and overall look of the website"},
                    {name: "JavaScript 2015", description: "Used for event handling, functionality and dynamics of the website"},
                    {name: "Vue JS", description: "JavaScript framework for component based programming which is used to create more dynamic websites"},
                    {name: "Django.py", description: "Python framewrok used for the backend of the website aka storing data, displaying data templates etc..."}
                ]
            },
            methods:{
                expand: function(){

                }
            }
        });
    </script>
</html>

0

3 Answers 3

3

To achieve desired behaviour, It'd be nice to have some property on object which indicated whether is thing visible or not.

eleObjects:[
    {name: "HTML5", description: "Used for front end web development more specifically for building the structure of a website", visible: false},
    {name: "CSS3", description: "Used for giving style to the HTML elements, their positioning and overall look of the website", visible:  false},
    {name: "JavaScript 2015", description: "Used for event handling, functionality and dynamics of the website", visible: false},
    {name: "Vue JS", description: "JavaScript framework for component based programming which is used to create more dynamic websites", visible: false},
    {name: "Django.py", description: "Python framewrok used for the backend of the website aka storing data, displaying data templates etc...", visible: false}
]

From v-for loop you can get the index, and same index pass to the expand function, so you can access to the clicked element from method.

<li v-for="(eleObject, index) in eleObjects">
    <h1 @click="expand(index)" v-text="eleObject.name"></h1>
    <h3 v-show="eleObject.visible" v-text="eleObject.description"></h3>
</li>

expand method should be rpetty straightforward, we only want to update visible state of clicked element.

expand: function(index){
   this.eleObjects[index].visible = !this.eleObjects[index].visible;
}

Here is the final demo: https://jsbin.com/jiduzoduri/1/edit?html,js,output

Sign up to request clarification or add additional context in comments.

Comments

1

In the mounted hook you need to alter the eleObjects array items by adding new field called show which is initially false and you use conditional rendering using v-show, then when you click on a specific item it will be expanded

let elementList = new Vue({
  el: "#elements",
  data: {
    eleObjects: [{
        name: "HTML5",
        description: "Used for front end web development more specifically for building the structure of a website"
      },
      {
        name: "CSS3",
        description: "Used for giving style to the HTML elements, their positioning and overall look of the website"
      },
      {
        name: "JavaScript 2015",
        description: "Used for event handling, functionality and dynamics of the website"
      },
      {
        name: "Vue JS",
        description: "JavaScript framework for component based programming which is used to create more dynamic websites"
      },
      {
        name: "Django.py",
        description: "Python framewrok used for the backend of the website aka storing data, displaying data templates etc..."
      }
    ]
  },

  methods: {
    expand: function(el, i) {
      el.show = true;

      this.$set(this.eleObjects, i, el);
    }
  },
  mounted() {
    this.eleObjects = this.eleObjects.map(e => {
      let t = e;
      e.show = false;
      return t;
    });
  }
});
* {
  margin: 0px;
  padding: 0px;
  font-family: sans-serif;
  list-style-type: none;
}

body {
  background: #003366;
}

#container {
  width: 1000px;
  margin: 100px auto;
}

#elements {
  width: 100%;
}

#elements li {
  display: inline-block;
  width: 40%;
  margin: 40px 5%;
  background: #FFF;
  color: #003366;
  box-shadow: 10px 10px 0px #222;
  user-select: none;
}

#elements li h1,
h3 {
  padding: 10px 20px;
}

#elements li h3 {}

#elements li h1 {
  cursor: pointer;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>


<body>
  <div id="container">
    <ul id='elements'>
      <li v-for="(eleObject,i) in eleObjects">
        <h1 v-on:click="expand(eleObject,i)" v-text="eleObject.name"></h1>
        <h3 v-text="eleObject.description" v-show="eleObject.show"></h3>
      </li>
    </ul>
  </div>
</body>

Comments

0

As you can read in the other answers, you can add a property to see if it is visible or not. Another way is that you can check the css and change it depending on whether it is block ornone

let elementList = new Vue({
  el: "#elements",
  data: {
    eleObjects: [{
        name: "HTML5",
        description: "Used for front end web development more specifically for building the structure of a website"
      },
      {
        name: "CSS3",
        description: "Used for giving style to the HTML elements, their positioning and overall look of the website"
      },
      {
        name: "JavaScript 2015",
        description: "Used for event handling, functionality and dynamics of the website"
      },
      {
        name: "Vue JS",
        description: "JavaScript framework for component based programming which is used to create more dynamic websites"
      },
      {
        name: "Django.py",
        description: "Python framewrok used for the backend of the website aka storing data, displaying data templates etc..."
      }
    ]
  },

  methods: {
    expand: function(e) {
      let h3Element = e.target.nextElementSibling;
      h3Element.style.display = (h3Element.style.display === 'block')? 'none':'block';
    }
  }
});
* {
  margin: 0px;
  padding: 0px;
  font-family: sans-serif;
  list-style-type: none;
}

body {
  background: #003366;
}

#container {
  width: 1000px;
  margin: 100px auto;
}

#elements {
  width: 100%;
}

#elements li {
  display: inline-block;
  width: 40%;
  margin: 40px 5%;
  background: #FFF;
  color: #003366;
  box-shadow: 10px 10px 0px #222;
  user-select: none;
}

#elements li h1,
h3 {
  padding: 10px 20px;
}

#elements li h3 {}

#elements li h1 {
  cursor: pointer;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>


<body>
  <div id="container">
    <ul id='elements'>
      <li v-for="(eleObject,i) in eleObjects">
        <h1 v-on:click="expand($event)" v-text="eleObject.name"></h1>
        <h3 v-text="eleObject.description" v-show="eleObject.show"></h3>
      </li>
    </ul>
  </div>
</body>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.