Vuejs

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

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 — для сокрытия/отображения макетов в зависимости от заданного представления.

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

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

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


Перевод статьи Francesco Bonizzi: Switching Between Grid View and List View With Vue.js