Symfony Vue
last modified July 5, 2020
Symfony Vue tutorial shows how to create a simple Symfony application with Vue frontend.
Symfony
Symfony is a set of reusable PHP components and a PHP framework for web projects. Symfony was published as free software in 2005. Symfony was inspired by Ruby on Rails, Django, and the Spring framework.
Symfony Encore is JavaScript library which is used to manage CSS and JavaScript in a Symfony application. Encore makes it easier to integrate Webpack into the Symfony application. It wraps Webpack, giving use a clean and powerful API for bundling JavaScript modules, pre-processing CSS and JavaScript, and compiling and minifying assets.
Vue
Vue is an open-source JavaScript framework for building user interfaces and single-page applications. It is an alternative to Angular and React.
Symfony Vue example
In the following example, we create a simple Symfony application that sends data in a template. The data is processed by Vue and displayed in a component.
In addition to PHP, we need to have Node.js installed. Have a look at ZetCode's Node.js tutorial for additional details.
Setting up the project
We show how to setup Symfony with Vue.
$ symfony new symvue
With symfony
CLI we create a new Symfony skeleton project.
$ cd symvue
We go to the project directory.
$ composer require maker --dev
In addition, we install the maker component. The maker
package
provides scaffolding.
$ composer req annot twig
We install components for working with annotations and templates.
$ composer require encore $ npm install
We install the Symfony Encore. This will install and enable the
WebpackEncoreBundle, add the assets
directory, create a
webpack.config.js
file, and add node_modules
to
.gitignore
.
$ npm i vue vue-loader vue-template-compiler
We install Vue and its libraries.
Project files
We show the important project files.
var Encore = require('@symfony/webpack-encore'); Encore .setOutputPath('public/build/') .setPublicPath('/build') .enableVueLoader() .addEntry('app', './assets/js/app.js') .splitEntryChunks() .enableSingleRuntimeChunk() .cleanupOutputBeforeBuild() .enableBuildNotifications() .enableSourceMaps(!Encore.isProduction()) .enableVersioning(Encore.isProduction()) ; module.exports = Encore.getWebpackConfig();
In the webpack.config.js
file, we enable
the Vue loader and set the public and build paths.
import Vue from 'vue'; import App from './components/App'; import '../css/app.css'; new Vue({ el: '#app', render: h => h(App) });
This is the main Vue file which starts Vue.
Symfony stores static files such as CSS and JavaScript in the assets
directory.
<template> <div> <h2 class="center">My Application</h2> <div v-text="message"></div> {{ message }} <ul> <li :key="word.id" v-for="word in words">{{ word }}</li> </ul> </div> </template> <script> export default { data() { return { message: "A list of words", words: [] }; }, mounted() { let el = document.querySelector("div[data-words]"); let mywords = el.dataset.words.split(","); this.words.push.apply(this.words, mywords); } }; </script> <style> .center { text-align: center; } </style>
This is the Vue component. A Vue application consists of components. A component consists of three parts: template, script, and style.
<div v-text="message"></div> {{ message }}
There are two ways to output variables in Vue; the second one is identical to Twig.
<ul> <li :key="word.id" v-for="word in words">{{ word }}</li> </ul>
With the v-for
directive, we go through the words
array and show each of the elements in a list item. The :key
directive helps Vue to render the list; it contains the Id of the
element.
The data originates
from a Symfony Twig template; it is processed by JavaScript and finally
output with v-for
in a Vue component.
data() { return { message: "A list of words", words: [] }; },
In the data()
function, we initiate a message variable
and the words
array.
mounted() { let el = document.querySelector("div[data-words]"); let mywords = el.dataset.words.split(","); this.words.push.apply(this.words, mywords); }
The words
array is filled with data in the mounted()
function, which parses data from an element's dataset. It is stored there
as a string; we split the string into words. The data is inserted in the
dataset inside Symfony's Twig template.
body { background-color: lightgray; }
We have some basic CSS in the app.css
.
$ php bin/console make:controller HomeController
The HomeController
is created with the Symfony maker.
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Routing\Annotation\Route; class HomeController extends AbstractController { /** * @Route("/home", name="home") */ public function index() { $words = ['sky', 'cloud', 'wood', 'rock', 'forest', 'mountain', 'breeze']; return $this->render('home/index.html.twig', [ 'words' => $words ]); } }
The controller method sends a list of words to the client.
return $this->render('home/index.html.twig', [ 'words' => $words ]);
We render the index.html.twig
template to which we
send the words.
{% extends 'base.html.twig' %} {% block title %}Home page{% endblock %} {% block body %} <div ref="words" data-words="{{ words|join(',') }}"> </div> <div id="app"> <app></app> </div> {% endblock %}
In the template, we add the words array to the data-words
attribute. The array is joined into a string with the Twig join
filter. The dataset
property on the HTMLElement interface provides
read/write access to all the custom data attributes (data-*) set on the element.
<div id="app"> <app></app> </div>
This is the entry point of the main Vue component.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{% block title %}Welcome!{% endblock %}</title> {% block stylesheets %} {{ encore_entry_link_tags('app') }} {% endblock %} </head> <body> {% block body %}{% endblock %} {% block javascripts %} {{ encore_entry_script_tags('app') }} {% endblock %} </body> </html>
This is the base template file.
{{ encore_entry_link_tags('app') }}
The CSS files are loaded with encore_entry_link_tags
.
{{ encore_entry_script_tags('app') }}
The JavaScript files are loaded with encore_entry_script_tags
.
Building assets
We need to build the assets.
$ npm run dev
The assets are built with npm run dev
command for the development
environment.
Running the application
We start the development server and locate to the application page.
$ symfony serve
We start the development server. Then we locate to the localhost:8000/home
page.
In this tutorial we have create a Symfony application that uses Vue on its frontend.
List all Symfony tutorials.