Есть страница со списком товаров, которые генереруются на PHP Хочу на JS собрать все необходимые данные по каждому товару: название, цена и другие. Потом на основе этих данных сгенерировать на VueJS карточки товара с другой разметкой. Я на js-фреймворках новичок. Пока только придумал создать компонент:
Vue.component('newProduct', {
template: `Здесь вся новая разметка товара`
});
И в него вставлять данные по каждой карточке товара, полученные гипотетически вот таким образом:
data: {
goods: [{
title: $('.titleProduct').text(),
price: $('.priceProduct').text()
},{
title: $('.titleProduct').text(),
price: $('.priceProduct').text()
}]
}
Не знаю как во вью правильно парсить... поэтому банально собрать по всему html как-нибудь данные И потом размножить компонент на полученное количество товаров:
<newProduct v-for="product in goods"></newProduct>
Предложите, пожалуйста, ваши варианты как это можно сделать проще именно на Vue. Может есть какие-то стандартные практики? Понятно, что правильнее сделать это на PHP, но нужно именно с этим фреймворком.
1 вариант
Один из распространенных вариантов, когда сервер по адресу /api/v1/products
возвращает данные в формате json. Ваше приложение, написанное на vuejs, взаимодействуем с сервером посредством ajax запроса с использованием обертки axios.
2 вариант
Еще один из вариантов - это передавать начальные данные в js до инициализации vue приложения, без необходимости их парсить/собирать по документу.
<script>
var scriptVariables = {
products: <?= json_encode($arrayProductsFromPhp) ?>
}
new Vue({
el: '#app',
data: {
// Наша модель с товарами.
// Берем из глобальной переменной.
products: scriptVariables.products
},
... Остальной код.
... В третьем варианте подробнее.
})
</script>
3 вариант
Vuejs не предоставляет каких-то специальных инструментов для парсинга html. Но есть специальный атрибут ref
для html тегов, который предоставляет прямой доступ к экземплярам дочерних компонентов и элементам. Нутром чувствую, что это сродни document.getElemntBy...
.
Так как вы только начали изучать vuejs думаю, вам будет интересен в качестве примера следующий код:
new Vue({
el: '#app',
data: {
// Наша модель с товарами. Изначально это пустой массив.
products: []
},
computed: {
/**
* В моделе содержится хоть один товар.
*/
issetProducts() {
return Boolean(this.products.length)
}
},
/**
* Используем хук `mounted` для инициализации сбора данных.
* Возможно, что в реальном проекте нужно будет воспользоваться
* async/await и возвращать Promise из метода `parseHtml`.
*/
mounted() {
// Запускаем парсинг.
this.parseHtml()
// Тут можем добавть класс к прелоадеру, чтобы скрыть его или удалить.
},
methods: {
parseHtml() {
// Для доступа к dom используем назначенную ранне ссылку:
// <table ref="productsTable">
let table = this.$refs.productsTable
this.parseHtmlTable(table)
this.removeTable(table)
},
/**
* Парсинг таблицы по ссылке. Никакой магии: native javascript.
*/
parseHtmlTable(table) {
// Выбираем первый body из таблицы: HTMLCollection [tbody].
let firstTableBody = table.tBodies[0]
// Получаем списоk всех строк из tBody.
let rows = firstTableBody.rows
// Проходимся по: HTMLCollection(4) [tr, tr, tr, tr].
// Не будем мудрить, т.к. мы знаем,
// что первая ячейка в строке - это название, вторая - цена.
for (let i = 0; i < rows.length; i++) {
// Добавляем данные в нашу модель товаров `products`.
this.products.push({
id: i + 1, // Насколько это правильно?
title: rows[i].cells[0].innerText,
price: rows[i].cells[1].innerText,
})
}
},
/**
* Скрываем/очищаем/удаляем таблицу из документа.
*/
removeTable(table) {
table.setAttribute('style', 'display:none')
}
}
})
<div id="app">
<!--Здесь лучше разместить какой-нибудь div-ный прелоадер на всю страницу. -->
<!-- Используем атрибут `ref` для регистрации ссылки и доступа к dom из vuejs. -->
<table ref="productsTable">
<caption>Список товаров с первоначальной разметкой</caption>
<tbody>
<tr><td>Первый товар</td><td>560</td></tr>
<tr><td>Второй товар</td><td>890</td></tr>
<tr><td>Третий товар</td><td>354</td></tr>
<tr><td>Четвертый товар</td><td>159</td></tr>
</tbody>
</table>
<!-- В рамках примера не будем выносить в отдельный компонент. -->
<h2 v-if="issetProducts">Список товаров с разметкой из vuejs</h2>
<template v-for="product in products" :key="product.id">
<p>{{ product.title }} <sup>{{ product.price }} фантик(ов)</sup></p>
</template>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
При переходе на новый алгоритм шифрования ГОСТ Р 3410-2012 256 сервер начал выдавать ошибку spki
Внимание! Это перевод вопроса What is the purpose of the ConcurrencyStamp column in the AspNetUsers table in the new ASPNET MVC 6 identity?
Нужно загрузить картинку с использованием HttpClientНо нижеприведенный код не работает