isGridView: true, isListView: true, methods: { switchView: function() { this.isGridView = !this.isGridView; }, switchData: function () { this.isListView = !this.isListView; }
<div class="product-grid1">item1</div> <div class="product-grid2">item2</div> <div class="product-grid3">item3</div> <div class="product-list1">item1</div> <div class="product-list2">item2</div> <div class="product-list3">item3</div> <div id="app-gridview"> <div> <button class="button" v-on:click="switchView()"></button> <button class="button" v-on:click="switchData()"></button> </div> <div v-bind:class="[ isGridView ? 'grid-wrapper' : 'list-wrapper' ]"> <div class="grid-row" v-if="isGridView"> <div class="grid-header" v-for="name in gridData.columns">{{ name }}</div> </div> <!-- GridView structure --> <div v-if="isGridView" class="grid-row" v-for="row in gridData.data"> <div class="list-row-item" v-for="name in gridData.columns"> <div>{{ row[name] }}</div> </div> </div> <!-- ListView structure --> <div v-if="!isGridView" class="list-row" v-for="row in gridData.data"> <img v-bind:src="row.ImagePath" class="list-image" /> <div class="list-property"> <div class="list-row-item" v-for="name in gridData.columns"> <div class="list-property-name">{{ name }}</div> <div>{{ row[name] }}</div> </div> </div> </div> </div>
I tried to implement the list and the grid view, Where I need to toggle between each one. For that i have taken isGrid and isList set to true, And from vue side i am trying to place ternary operator, And switch between each other.
Can you please help me on toggle from the list and grid view.
Advertisement
Answer
When you create a component whose view can be changed, I suggest that you use the container-presentational component pattern. Really easy to keep track, and it’s a breeze to add a new “view” of the data.
// this is the grid view // this is a presentational component: // only displays what is passed through props Vue.component("GridView", { props: ["users"], computed: { headers() { if (!this.users.length) return [] return Object.keys(this.users[0]) }, }, template: ` <table> <thead> <tr> <th v-for="header in headers" :key="header" > {{ header }} </th> </tr> </thead> <tbody> <tr v-for="user in users" :key="user.id" > <td v-for="(val, key) in user" :key="user.id + '-' + key" > {{ val }} </td> </tr> </tbody> </table> ` }) // this is the list view // this is a presentational component: // only displays what is passed through props Vue.component("ListView", { props: ["users"], template: ` <ol> <li v-for="user in users" :key="user.id" > <div v-for="(val, key) in user" :key="user.id + '-' + key" > {{ key }}: {{ val }} </div> </li> </ol> ` }) // this component handles the data: // fetching, mapping, transforming, etc. // this is a renderless component Vue.component("DataContainer", { data() { return { users: [] } }, mounted() { this.fetchUsers() }, methods: { async fetchUsers() { try { const response = await fetch('https://jsonplaceholder.typicode.com/users') const json = await response.json() this.users = json.map(({ id, name, username, email }) => ({ id, name, username, email })) } catch (err) { console.error(err) } } }, render(h) { // renders nothing, just provides the data // by passing it through "users" return this.$scopedSlots.default({ users: this.users, }) }, }) // the Vue instance new Vue({ el: "#app", data() { return { layout: "list-view", } }, methods: { switchView() { this.layout = this.layout === "list-view" ? "grid-view" : "list-view" } }, template: ` <div> <button @click="switchView" > SWITCH VIEW </button> <data-container> <template #default="{ users }" > <component :is="layout" v-bind="{ users }" /> </template> </data-container> </div> `, })
table { border-collapse: collapse; } table, tr, th, td { border: 1px solid black; } td, th { padding: 4px 8px; } th { background-color: rgba(0, 0, 0, 0.3); }
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"></div>
I understand that this is a bit further away from correcting a v-if
condition-handling – but this setup would help you create flexible, extensible & maintainable solution.