PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Vue.js dla PHP developera – Options API, Composition API, komunikacja z Magento REST

by Henryk Tews / wtorek, 08 września 2020 / Opublikowano w JavaScript

Jako PHP developer pewnie masz za sobą kontakt z jQuery i może trochę czystego JS. Vue.js to kolejny krok – reaktywny framework, który coraz częściej pojawia się w projektach e-commerce jako warstwa frontendowa przy headless Magento lub jako zamiennik starszego knockout.js. Pokazuję podstawy z perspektywy kogoś, kto na co dzień myśli w PHP.

Dlaczego Vue, a nie React czy Angular?

React wymaga myślenia w JSX i ma bardziej stromą krzywą uczenia się. Angular to pełny framework z rozbudowaną architekturą – overkill do małych komponentów. Vue zajmuje środek: prosta składnia szablonów bliska HTML, reaktywność wbudowana bez ceremonii, dokumentacja w języku polskim. Dla PHP developera, który nie jest frontendowcem z wyboru, Vue jest najłagodniejszym wejściem w świat komponentów.

W ekosystemie Magento Vue pojawia się w Vue Storefront – najpopularniejszym headless frontend dla Magento 2.

Podstawowa struktura komponentu Vue 3

// Komponent Vue 3 - Options API (prostszy dla przybyszów z PHP)
const ProductCard = {
    // Dane komponentu - odpowiednik właściwości klasy PHP
    data() {
        return {
            quantity: 1,
            addedToCart: false,
        };
    },

    // Właściwości przekazywane z zewnątrz - odpowiednik parametrów metody
    props: {
        product: {
            type: Object,
            required: true,
        },
        maxQuantity: {
            type: Number,
            default: 99,
        },
    },

    // Obliczone właściwości - odpowiednik getterów w PHP
    computed: {
        totalPrice() {
            return (this.product.price * this.quantity).toFixed(2);
        },
        canAddMore() {
            return this.quantity < this.maxQuantity;
        },
    },

    // Metody - odpowiednik metod klasy PHP
    methods: {
        addToCart() {
            if (!this.canAddMore) return;

            // Wywołanie API lub emitowanie zdarzenia do rodzica
            this.$emit('add-to-cart', {
                productId: this.product.id,
                quantity:  this.quantity,
            });

            this.addedToCart = true;
        },
        increment() {
            if (this.quantity < this.maxQuantity) {
                this.quantity++;
            }
        },
        decrement() {
            if (this.quantity > 1) {
                this.quantity--;
            }
        },
    },

    // Szablon HTML z dyrektywami Vue
    template: `
        <div class="product-card">
            <h3>{{ product.name }}</h3>
            <p class="price">{{ totalPrice }} PLN</p>

            <div class="quantity-control">
                <button @click="decrement" :disabled="quantity <= 1">-</button>
                <span>{{ quantity }}</span>
                <button @click="increment" :disabled="!canAddMore">+</button>
            </div>

            <button @click="addToCart" :class="{ 'btn-success': addedToCart }">
                {{ addedToCart ? 'Dodano!' : 'Dodaj do koszyka' }}
            </button>
        </div>
    `,
};

Dyrektywy Vue – odpowiedniki z PHP

Vue dyrektywa Co robi Analogia PHP/Twig
{{ variable }} Wyświetla wartość <?= $var ?>
v-if="condition" Warunkowe renderowanie {% if condition %}
v-for="item in items" Pętla po tablicy {% for item in items %}
v-model="variable" Dwukierunkowe wiązanie z inputem brak bezpośredniego odpowiednika
@click="method" Obsługa zdarzenia click brak (to jest JS)
:class="object" Dynamiczne klasy CSS class="{{ condition ? 'a' : 'b' }}"

Komunikacja z Magento API przez Vue

// Pobieranie danych z Magento 2 REST API w komponencie Vue
const ProductList = {
    data() {
        return {
            products: [],
            loading: false,
            error: null,
        };
    },

    async mounted() {
        await this.fetchProducts();
    },

    methods: {
        async fetchProducts() {
            this.loading = true;
            this.error   = null;

            try {
                const response = await fetch(
                    '/rest/V1/products?searchCriteria[pageSize]=12&searchCriteria[currentPage]=1',
                    {
                        headers: {
                            'Content-Type': 'application/json',
                            // Token dla zalogowanego klienta
                            // 'Authorization': 'Bearer ' + customerToken,
                        },
                    }
                );

                if (!response.ok) {
                    throw new Error('API error: ' + response.status);
                }

                const data = await response.json();
                this.products = data.items;

            } catch (err) {
                this.error = err.message;
            } finally {
                this.loading = false;
            }
        },
    },

    template: `
        <div>
            <div v-if="loading">Ładowanie...</div>
            <div v-else-if="error">Błąd: {{ error }}</div>
            <div v-else>
                <product-card
                    v-for="product in products"
                    :key="product.id"
                    :product="product"
                    @add-to-cart="handleAddToCart"
                />
            </div>
        </div>
    `,
};

Composition API – podejście bardziej "PHP-owe"

Vue 3 wprowadził Composition API – alternatywę dla Options API, gdzie logikę grupujesz funkcjami zamiast opcjami obiektu. Dla PHP developera przyzwyczajonego do klas i metod, Composition API może być bardziej intuicyjne:

import { ref, computed, onMounted } from 'vue';

// Composition API - setup() zamiast data/methods/computed
export default {
    props: ['productId'],

    setup(props) {
        // ref() to odpowiednik właściwości klasy - reaktywna wartość
        const product  = ref(null);
        const quantity = ref(1);
        const loading  = ref(false);

        // computed - odpowiednik gettera
        const totalPrice = computed(() => {
            return product.value
                ? (product.value.price * quantity.value).toFixed(2)
                : '0.00';
        });

        // Funkcja - odpowiednik metody
        async function loadProduct() {
            loading.value = true;
            const response = await fetch('/rest/V1/products/' + props.productId);
            product.value = await response.json();
            loading.value = false;
        }

        // Hak cyklu życia - uruchom po zamontowaniu komponentu
        onMounted(loadProduct);

        // Eksportuj to co ma być dostępne w template
        return { product, quantity, totalPrice, loading };
    },
};

Podsumowanie

Vue.js ma łagodną krzywą uczenia się – komponent z Options API jest strukturalnie podobny do klasy PHP z właściwościami i metodami. Reaktywność (automatyczna aktualizacja widoku przy zmianie danych) to największa zmiana w myśleniu względem klasycznego PHP, gdzie renderowanie to jednorazowy proces. Jeśli planujesz pracę z Vue Storefront lub budujesz interaktywne komponenty dla sklepu Magento – warto poświęcić na Vue kilka weekendów.

About Henryk Tews

Co możesz przeczytać następne

Next.js dla PHP developera – SSR, Server Components, GraphQL z Magento, porównanie z MVC
React.js – JSX, useState, useEffect, custom hooks, porównanie z Vue
TypeScript dla PHP developera – typy, interface, generics, async/await
  • Publikacje
  • O autorze
  • Kontakt

© 2026 Created by

GÓRA
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Zawsze aktywne
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Zarządzaj opcjami
  • Zarządzaj serwisami
  • Zarządzaj {vendor_count} dostawcami
  • Przeczytaj więcej o tych celach
Zobacz preferencje
  • {title}
  • {title}
  • {title}