In the highly improbable case you would need to plug Vue.js into a Symfony 1.4 app, here is how I did it.
No webpack.
Gulp was used with gulp-babel and gulp-polyfill to support ES6 and async/await.
// web/assets/javascripts/frontend/modules/acme/acme.js | |
/** | |
* ASYNC/AWAIT | |
* REQUIRE BABEL AND POLYFILL | |
* Vue.js https://vuejs.org/ | |
* axios https://github.com/axios/axios | |
*/ | |
var App = (App => { | |
// Components | |
const StatTableProducts = Vue.component("stat-table-products", { | |
props: ["products", "search"], | |
data() { | |
return { | |
headers: [ | |
{ text: "ID", value: "id" }, | |
{ text: "Quantity", value: "qty" }, | |
{ text: "Designation", value: "designation" }, | |
{ text: "Reference", value: "reference" } | |
], | |
tmp: "", | |
pagination: { | |
sortBy: "qty", | |
descending: true | |
} | |
}; | |
}, | |
template: "#stat-table-products-template", | |
mounted() { | |
App.loader.enable(this.$el); | |
}, | |
watch: { | |
products() { | |
App.loader.disable(this.$el); | |
} | |
} | |
}); | |
const Acme = Vue.component("acme", { | |
template: "#acme-template", | |
data() { | |
return { | |
root: document.firstElementChild.dataset.root, | |
ajaxParams: { | |
headers: { "X-Requested-With": "XMLHttpRequest" }, | |
params: {} | |
}, | |
products: { | |
title: "Products", | |
data: [] | |
}, | |
search: "" | |
}; | |
}, | |
async beforeMount() { | |
this.getTopProducts(); | |
}, | |
methods: { | |
async getTopProducts() { | |
await axios | |
.get("/api/products", this.ajaxParams) | |
.then(response => (this.products.data = response.data)); | |
} | |
} | |
}); | |
// Vue instance | |
document.addEventListener("DOMContentLoaded", () => { | |
const acmeModule = new Vue({ | |
el: "#acme", | |
data() { | |
return { | |
drawer: false | |
}; | |
}, | |
components: { | |
StatTableProducts | |
} | |
}); | |
App.acmeModule = acmeModule; | |
}); | |
return App; | |
})(App || {}); |
<?php //app/frontend/modules/acme/templates/_acme/acme.php.php ?> | |
<script type="text/x-template" id="acme-template"> | |
<v-container grid-list-md text-xs-center> | |
<v-layout row wrap> | |
<v-flex xs12 md6> | |
<v-expansion-panel expand> | |
<v-expansion-panel-content> | |
<div slot="header"> | |
<h3 class="box-title"> | |
{{ products.title }} | |
</h3> | |
</div> | |
<!-- Search --> | |
<v-text-field | |
append-icon="search" | |
label="Search" | |
single-line | |
hide-details | |
v-model="search" | |
></v-text-field> | |
<stat-table-products id="stat-table-products" :products="products.data" :search="search"></stat-table-products> | |
</v-expansion-panel-content> | |
</v-expansion-panel> | |
</v-flex> | |
</v-layout> | |
</v-container> | |
</script> |
<?php | |
//apps/frontend/modules/acme/actions/acmeAction.class.php | |
// no namespace in symfony 1.4 ! | |
/** | |
* @author bernard[dot]pagoaga[at]gmail.com | |
*/ | |
class AcmeAction extends BaseAction { | |
/** | |
* Default action | |
* | |
* @param $request | |
*/ | |
public function execute($request) { | |
// nothing to see here | |
// execute some code if needed | |
} | |
} |
<?php | |
// app/frontend/modules/acme/templates/indexSuccess.php | |
/** | |
* Experimental module to plug Vue.js into a Symfony 1.4 app | |
* @author bernard[dot]pagoaga[at]gmail.com | |
*/ | |
// Assets | |
use_stylesheet('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'); | |
use_stylesheet('https://unpkg.com/vuetify/dist/vuetify.min.css'); | |
use_stylesheet('/assets/stylesheets/frontend/modules/acme/acme.css'); | |
use_javascript('https://unpkg.com/axios/dist/axios.min.js'); | |
use_javascript('https://cdn.jsdelivr.net/npm/vue/dist/vue.js'); | |
use_javascript('https://unpkg.com/vuetify/dist/vuetify.js'); | |
use_javascript('/assets/javascripts/frontend/modules/acme/acme.js'); | |
// Vue components | |
include_partial('acme/acme/acme'); | |
include_partial('acme/acme/statTableProducts'); | |
?> | |
<div id="acme"> | |
<v-app> | |
<main> | |
<v-container fluid> | |
<acme></acme> | |
</v-container> | |
</main> | |
</v-app> | |
</div> | |