Переключение между табличным и списковым представлением в Vue.js

Представляйте любой массив данных и переключайтесь между визуализациями

Olga Sayfudinova
Nov 5 · 5 min read

Vue.js — это простой в изучении, быстрый, легковесный и очень перспективный фреймворк.

В данной статье я расскажу о создании Vue приложения для представления текстовых данных из массива и изменения их визуализации (табличный и списковый вид).

Конечный результат доступен в репозитории.

Первые шаги

Для начала создадим три новых файла:

  • index.html
  • app.js
  • style.css

В файле index.html пропишем таблицу стилей, JavaScript файл и, конечно же, Vue.js:

<head>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<link href="style.css" rel="stylesheet" />
</head>

Теперь придумайте дизайн приложения:

В нашем приложении будет следующее:

  • Кнопка для переключения между табличным и списковым представлением.
  • Кнопка для переключения между массивами данных. Так вы показываете, что приложение может отображать различные коллекции.
  • Стандартный табличный вид. Первая строка — название столбца. Каждый элемент размещается в отдельной строке.
  • Списковое представление: каждый элемент становится частью вертикальной коллекции со своим изображением.

Табличное представление без Vue.js

Реализация табличного вида без Vue.js выглядит так:

<div id="app-gridview">

<div>
<button class="button"><span>Switch to ListView</span></button>
<button class="button"><span>Switch to books data</span></button>
</div>

<div class="grid-wrapper">

<div class="grid-row">
<div class="grid-header">Column 1</div>
<div class="grid-header">Column 2</div>
<div class="grid-header">Column 3</div>
</div>

<!-- Структура табличного представления -->
<div class="grid-row">

<div class="list-row-item">
<div>Column 1 Value a</div>
<div>Column 2 Value b</div>
<div>Column 3 Value c</div>
</div>

<div class="list-row-item">
<div>Column 1 Value d</div>
<div>Column 2 Value e</div>
<div>Column 3 Value f</div>
</div>

</div>

</div>

</div>

Как видите, я не пользовался тегом table, а ограничился только div. Куда удобнее реализовать смену представлений через css:

.grid-wrapper {
display: table;
border: 4px solid #336699;
border-radius: 6px;
transition: all ease 0.5s;
}

.grid-header {
font-weight: bold;
background: #336699;
color: white;
border-bottom: 4px solid #f6f6f6;
}

.grid-row {
display: table-row;
}

.grid-row > div {
display: table-cell;
padding: 10px 20px;
}

.grid-wrapper > div:nth-child(even) {
background: #f6f6f6;
transition: all ease 0.4s;
}

.grid-wrapper > div:nth-child(odd) {
background: #fafafa;
transition: all ease 0.4s;
}

.grid-wrapper > div:hover {
background: #a9d6ff;
transition: all ease 0.4s;
}

На что обратить внимание:

  • grid-wrapper, display: table
  • grid-row, display: table-row

Выглядит примерно так:

Списковое представление без Vue.js

Списковое представление без Vue.js выглядит вот так:

<div class="list-wrapper">

<!-- Структура спискового представления -->
<div class="list-row">

<img src="images/a.jpg" class="list-image" />

<div class="list-property">
<div class="list-row-item">
<div class="list-property-name">Column 1</div>
<div>Value a</div>
</div>

<div class="list-row-item">
<div class="list-property-name">Column 2</div>
<div>Value b</div>
</div>

<div class="list-row-item">
<div class="list-property-name">Column 3</div>
<div>Value c</div>
</div>

</div>
</div>

<!-- И т.д. -->

</div>

Этот стиль очень простой и представляет собой сочетание display: grid с flexbox:

.list-row {
padding: 10px;
margin: 10px;
background: white;
border-radius: 6px;
-webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.37);
-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.37);
box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.37);
display: grid;
grid-template-columns: auto 1fr;
width: 600px;
}

.list-row-item {
display: grid;
grid-template-columns: 150px 1fr;
padding: 4px;
transition: all 0.5s;
}

.list-property {
display: flex;
flex-direction: column;
justify-content: space-between;
}

.list-property-name {
font-weight: bold;
transition: all 0.5s;
}

.list-image {
width: 150px;
border-radius: 6px;
margin-right: 10px;
}

И получается вот это:

Интеграция Vue.js

Объект для представления выглядит примерно так:

var booksData = {
columns: [
"Id",
"Name",
"Author",
"Theme",
"Rating"
],
data: [
{ Id: 1, Name: "The look of love", Author: "George Blue", Theme: "Drama", Rating: "*****", ImagePath: "images/a.jpg" },
{ Id: 2, Name: "20 vegetarian dishes", Author: "Francesco Bonizzi", Theme: "Cooking", Rating: "****", ImagePath: "images/b.jpg" },
{ Id: 3, Name: "How to be happy", Author: "Asdrubale Anselmi", Theme: "Self help", Rating: "*", ImagePath: "images/c.jpg" },
{ Id: 4, Name: "The last bee", Author: "John Dorian", Theme: "Nature", Rating: "****", ImagePath: "images/d.jpg" }
]
};

Обратите внимание, что в нем есть два массива:

  • columns с перечнем (именами) свойств для отображения;
  • data — массив объектов со свойствами из columns.

Настало время реализовать наше приложение в Vue:

var gridviewApp = new Vue({

el: '#app-gridview',

data: {
gridData: cartData,
buttonSwitchViewText: "Switch to ListView",
buttonSwitchDataText: "Switch to books data",
isGridView: true,
isBookData: false
},

methods: {

switchView: function() {

if (this.isGridView) {
this.buttonSwitchViewText = "Switch to GridView";
}
else {
this.buttonSwitchViewText = "Switch to ListView";
}

this.isGridView = !this.isGridView;
},

switchData: function () {

if (this.isBookData) {
this.buttonSwitchDataText = "Switch to books data";
this.gridData = cartData;
}
else {
this.buttonSwitchDataText = "Switch to shop data";
this.gridData = booksData;
}

this.isBookData = !this.isBookData;
}

}

});

У нас получилось очень простое приложение:

  • isGridView — свойство для отображения/сокрытия табличного или спискового представления макета.
  • isBookData — свойство для изменения представляемых данных. В рабочей версии оно не понадобится, а здесь используется для обучающих целей.
  • Все тестовые данные есть в репозитории.

Самое интересное здесь — это структура HTML, которая представляет собой сочетание следующих элементов:

  • v-bind:class для переключения списковых/табличных CSS классов в зависимости от значения isGridViewCondition
  • v-for для отображения значений массивов и названий столбцов;
  • v-if — для сокрытия/отображения макетов в зависимости от заданного представления.

А вот и конечный результат:

Весь код можно найти в репозитории.

Читайте также:

Читайте нас в Телеграмме: https://t.me/nuancesprog и ВК: https://vk.com/nuancesprog


Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade