Scout APM is PHP application performance monitoring designed for developers. With tracing logic that ties issues back to the line of code causing them, you can pinpoint n+1 queries, memory leaks, and other abnormalities in real time so you can knock them out and get back to building a great product. Start your free 14-day trial today and get the performance insight you need in less than 4 minutes.

Introducing BladeX View Models

Original – by Freek Van der Herten – 3 minute read

Earlier today we released BladeX, a package that allows you to use Blade components using a Vue inspired syntax. Read all about it in my previous blogpost.

In the latest North Meets South podcast Jacob and Michael discussed BladeX and wondered if the package could be married with view models or Laravel's View Composers. Our team discussed this too last Friday but we decided to release the core features of BladeX first. After the release today it became apparent pretty fast that we needed some sort of view model support in our projects too. So we got to work!

I'm happy to share that v1.1 of BladeX now has support for view models. In this blogpost I'd like to walk you through the feature.

Using view models

View models are used to transform data before a BladeX component is rendered. Let's make the usage clear with an example. We are going to render a select element to render a select element with some countries.

To make a BladeX component use a view model you need to tack on a call to viewModel when you register the component. The class name of the view model is pass to that method.


Before reviewing the contents of the component and the view model itself, let's take a look first on how we are going to use component.

// in a real app this data would most likely come from a controller
$countries = [
    'be' => 'Belgium',
    'fr' => 'France',
    'nl' => 'The Netherlands',

<select-field name="countries" :options="$countries" selected="fr" />

Next, let's take a look at what the SelectViewModel::class looks like:

class SelectViewModel extends ViewModel
    /** @var string */
    public $name;

    /** @var array */
    public $options;

    /** @var string */
    public $selected;

    public function __construct(string $name, array $options, string $selected = null)
        $this->name = $name;

        $this->options = $options;

        $this->selected = $selected;

    public function isSelected(string $optionName): bool
        return $optionName === $this->selected;

Notice that this class extends \Spatie\BladeX\ViewModel. Every attribute on select-field is being passed to the constructor. This passing is being done name based, the name attribute will be passed to a constructor argument named $name, the options attribute will be passed to $options and so on. Any other argument will be resolved out of the ioc container. This can be handy for dependency injection.

All public properties and methods of the view model will be passed to the Blade view that will render the select-field component. Public methods will be available in as a closure stored in the variable that is named after the public method in view model. This is what that view looks like.

<select name="{{ $name }}">
    @foreach($options as $value => $label)
        <option {!! $isSelected($value) ? 'selected="selected"' : '' !!} name="{{ $value }}">{{ $label }}</option>

When rendering the BladeX component, this is the output:

  <select name="countries">
    <option name="be">Belgium</option>
    <option selected="selected" name="fr">France</option>
    <option name="nl">The Netherlands</option>

If you have any remarks of questions about this, let me know in the comments below.

Stay up to date with all things Laravel, PHP, and JavaScript.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.