JavaScript
x
15
15
1
isGridView: true,
2
isListView: true,
3
4
methods: {
5
6
switchView: function() {
7
8
this.isGridView = !this.isGridView;
9
10
},
11
12
switchData: function () {
13
14
this.isListView = !this.isListView;
15
}
JavaScript
1
40
40
1
<div class="product-grid1">item1</div>
2
<div class="product-grid2">item2</div>
3
<div class="product-grid3">item3</div>
4
5
<div class="product-list1">item1</div>
6
<div class="product-list2">item2</div>
7
<div class="product-list3">item3</div>
8
9
<div id="app-gridview">
10
11
<div>
12
<button class="button" v-on:click="switchView()"></button>
13
<button class="button" v-on:click="switchData()"></button>
14
</div>
15
16
<div v-bind:class="[ isGridView ? 'grid-wrapper' : 'list-wrapper' ]">
17
18
<div class="grid-row" v-if="isGridView">
19
<div class="grid-header" v-for="name in gridData.columns">{{ name }}</div>
20
</div>
21
22
<!-- GridView structure -->
23
<div v-if="isGridView" class="grid-row" v-for="row in gridData.data">
24
<div class="list-row-item" v-for="name in gridData.columns">
25
<div>{{ row[name] }}</div>
26
</div>
27
</div>
28
29
<!-- ListView structure -->
30
<div v-if="!isGridView" class="list-row" v-for="row in gridData.data">
31
<img v-bind:src="row.ImagePath" class="list-image" />
32
<div class="list-property">
33
<div class="list-row-item" v-for="name in gridData.columns">
34
<div class="list-property-name">{{ name }}</div>
35
<div>{{ row[name] }}</div>
36
</div>
37
</div>
38
</div>
39
40
</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.
JavaScript
1
137
137
1
// this is the grid view
2
// this is a presentational component:
3
// only displays what is passed through props
4
Vue.component("GridView", {
5
props: ["users"],
6
computed: {
7
headers() {
8
if (!this.users.length) return []
9
return Object.keys(this.users[0])
10
},
11
},
12
template: `
13
<table>
14
<thead>
15
<tr>
16
<th
17
v-for="header in headers"
18
:key="header"
19
>
20
{{ header }}
21
</th>
22
</tr>
23
</thead>
24
<tbody>
25
<tr
26
v-for="user in users"
27
:key="user.id"
28
>
29
<td
30
v-for="(val, key) in user"
31
:key="user.id + '-' + key"
32
>
33
{{ val }}
34
</td>
35
</tr>
36
</tbody>
37
</table>
38
`
39
})
40
41
// this is the list view
42
// this is a presentational component:
43
// only displays what is passed through props
44
Vue.component("ListView", {
45
props: ["users"],
46
template: `
47
<ol>
48
<li
49
v-for="user in users"
50
:key="user.id"
51
>
52
<div
53
v-for="(val, key) in user"
54
:key="user.id + '-' + key"
55
>
56
{{ key }}: {{ val }}
57
</div>
58
</li>
59
</ol>
60
`
61
})
62
63
// this component handles the data:
64
// fetching, mapping, transforming, etc.
65
// this is a renderless component
66
Vue.component("DataContainer", {
67
data() {
68
return {
69
users: []
70
}
71
},
72
mounted() {
73
this.fetchUsers()
74
},
75
methods: {
76
async fetchUsers() {
77
try {
78
const response = await fetch('https://jsonplaceholder.typicode.com/users')
79
const json = await response.json()
80
this.users = json.map(({
81
id,
82
name,
83
username,
84
email
85
}) => ({
86
id,
87
name,
88
username,
89
email
90
}))
91
} catch (err) {
92
console.error(err)
93
}
94
}
95
},
96
render(h) {
97
// renders nothing, just provides the data
98
// by passing it through "users"
99
return this.$scopedSlots.default({
100
users: this.users,
101
})
102
},
103
})
104
105
// the Vue instance
106
new Vue({
107
el: "#app",
108
data() {
109
return {
110
layout: "list-view",
111
}
112
},
113
methods: {
114
switchView() {
115
this.layout = this.layout === "list-view" ? "grid-view" : "list-view"
116
}
117
},
118
template: `
119
<div>
120
<button
121
@click="switchView"
122
>
123
SWITCH VIEW
124
</button>
125
<data-container>
126
<template
127
#default="{ users }"
128
>
129
<component
130
:is="layout"
131
v-bind="{ users }"
132
/>
133
</template>
134
</data-container>
135
</div>
136
`,
137
})
JavaScript
1
19
19
1
table {
2
border-collapse: collapse;
3
}
4
5
table,
6
tr,
7
th,
8
td {
9
border: 1px solid black;
10
}
11
12
td,
13
th {
14
padding: 4px 8px;
15
}
16
17
th {
18
background-color: rgba(0, 0, 0, 0.3);
19
}
JavaScript
1
2
1
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
2
<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.