Reputation: 730
I'm trying to convert an UI element to a component, to reuse it. It's two buttons, to toggle the visibility of two DOM elements in parent app. The value is saved in local storage.
I reviewed several examples and the docu, and I was able to create a working example.
https://jsfiddle.net/d6xbts4h/2/
What I would like to get to is, to remove this.layout
and toggleLayout()
from the parent app and just drop in <toggle-view v-on:layout="toggleLayout" route="checklist"></toggle-view>
and define that div#list-content
and div#grid-content
only be shown if respective component button is activated. Is that possible?
The reason why I want to get rid of additional methods in the parent app, is laziness. I want to deal with the logic in the component only.
I appreciate your time and input.
Vue.component('toggle-view', {
props: ['route'],
data: function () {
return {
// load value from local storage or set default value
layout: Vue.ls.get(this.route + '__layout','list'), // list|grid
}
},
template: `<div class="btn-group" role="group" aria-label="Basic example">
<button id="list-toggle" v-on:click="setLayout('list', $event)" type="button" :class="[layout == 'list' ? 'active' : '' , 'btn', 'btn-secondary']"><i class="material-icons">view_list</i></button>
<button id="grid-toggle" v-on:click="setLayout('grid', $event)" type="button" :class="[layout == 'grid' ? 'active' : '' , 'btn', 'btn-secondary']"><i class="material-icons">view_module</i></button>
</div>`,
mounted: function(){
// init the layout and $emit it to parent
this.setLayout(this.layout)
},
methods:{
setLayout: function(layout,event){
this.$emit('layout', layout);
this.layout = layout;
Vue.ls.set(this.route + '__layout',layout);
console.log(layout);
}
},
});
var app = new Vue({
el: '#app',
data: {layout:null},
methods:{
toggleLayout: function(layout){
this.layout = layout;
}
},
});
<div id="app">
<toggle-view v-on:layout="toggleLayout" route="checklist"></toggle-view>
<div v-if="layout === 'list'" id="list-content" class="list">
Liste
</div>
<div v-if="layout === 'grid'" id="grid-content" class="grid">
grid
</div>
</div>
Upvotes: 0
Views: 918
Reputation: 1620
Your child component should not be aware of the parent component. It's simply bad practice to "couple" the child component to the parent.
You should write the additional method in your parent component because this is the component which is affected by the users action.
Dispatching an event in your component (as you already do) is the correct way to handle this.
There was a possibility to do this in older Vue Versions, but it has been removed due to caveats. (https://012.vuejs.org/guide/components.html#Inheriting_Parent_Scope)
Upvotes: 1