Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js: Collapse/expand all elements from parent

I need to add "expand/collapse all" functionality for my Vue component(some collapsible panel).

If user clicks collapse button then clicks on some panel and expand it then clicking on collapse button will do nothing because watched parameter will not change.

So how to implement this functionality properly (buttons must collapse and expand components always)?

I prepared simple example(sorry for bad formatting, it looks nice in editor :( ):

var collapsible = {
  template: "#collapsible",
  props: ["collapseAll"],
  data: function () {
      return {
        collapsed: true
    }
  },
  watch: {
  	collapseAll: function(value) {
    	this.collapsed = value
    }
  }
}

var app = new Vue({
	template: "#app",
  el: "#foo",
  data: {
      collapseAll: true
  },
  components: {
  	collapsible: collapsible
  }
});
.wrapper {
  width: 100%;
}

.wrapper + .wrapper {
  margin-top: 10px;
}

.header {
  height: 20px;
  width: 100%;
  background: #ccc;
}

.collapsible {
  height: 100px;
  width: 100%;
  background: #aaa;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>

<div id="foo"></div>


<script type="text/x-template" id="collapsible">
 	<div class="wrapper">
    <div class="header" v-on:click="collapsed = !collapsed"></div>
    <div class="collapsible" v-show="!collapsed"></div>
	</div>
</script>


<script type="text/x-template" id="app">
	<div>
    <button v-on:click="collapseAll = true">Collapse All</button>
    <button v-on:click="collapseAll = false">Expand All</button>
 		<collapsible v-for="a in 10" v-bind:collapseAll="collapseAll" v-bind:key="a"></collapsible>
  </div>
</script>

Thanks!

like image 298
Max Sinev Avatar asked May 21 '17 20:05

Max Sinev


1 Answers

This is a case where I might use a ref.

<button v-on:click="collapseAll">Collapse All</button>
<button v-on:click="expandAll">Expand All</button>
<collapsible ref="collapsible" v-for="a in 10" v-bind:key="a"></collapsible>

And add methods to your Vue.

var app = new Vue({
    template: "#app",
  el: "#foo",
  methods:{
    collapseAll(){
      this.$refs.collapsible.map(c => c.collapsed = true)
    },
    expandAll(){
      this.$refs.collapsible.map(c => c.collapsed = false)
    }
  },
  components: {
    collapsible: collapsible
  }
});

Example.

like image 50
Bert Avatar answered Nov 08 '22 19:11

Bert