A simple solution integrating Vue in TYPO3. I'm using webpack as bundler, but every other bundler should also work. This way may not be the best to integrate Vue in TYPO3, but is super easy and has no limitations writing your Vue code, which comes in place if you try to use eg. the EXT:vuejs.
The Vue app itselfs looks like any other Vue app. I added only the bundled JS file in the HTML Template of my extension, and tell my contoller he has to spit out JSON, which is used as initial dataset for the app.
Here some code examples. I created a demo extension which holds an BE module and FE plugin for a Todolist. The BE module will show the same as the FE plugin, simply to demonstrate that the usage in the BE works on same way.
Let's start with the Controller. The listAction() maps the findAll() result into an simple array. The function toArray() was also added from me i the todo model. And we assign the JSON to the List.html template
/Classes/Controller/TodoController.php public function listAction() { $todos = $this->todoRepository->findAll(); $todos = array_map(function ($todo) { return $todo->toArray(); }, $todos->toArray()); $this->view->assign('json', json_encode($todos)); return $this->htmlResponse(); }
/Domain/Model/Todo.phppublic function toArray() { return [ 'uid' => $this->getUid(), 'title' => $this->getTitle(), 'done' => $this->isDone(), ]; }
/Templates/Todo/List.html <f:section name="content"> <f:flashMessages /> <div id="app"></div> <script> var json = <f:format.raw>{json}</f:format.raw> </script> <f:asset.script identifier="app" src="EXT:example_vue_simple/Resources/Public/JavaScript/app.bundle.js"></f:asset.script> </f:section>
The JS file app.bundle.js of the Vue app was included in the HTML template. Let's start with a demo app code, first comes the webpack.config.js file.
While I develop the app, I use the "webpack --watch" command, so the app codes gets rendered.
/Public/JavaScript/App/webpack.config.jsconst path = require("path"); const webpack = require("webpack"); const { VueLoaderPlugin } = require('vue-loader') module.exports = { entry: { app: "./src/main.js" }, mode: "development", output: { filename: "[name].bundle.js", path: path.resolve(__dirname, "../") }, plugins: [ new VueLoaderPlugin(), new webpack.DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }), ], module: { rules: [ { test: /\.vue$/, loader: 'vue-loader' } ] } };
I created a simple Vue app in the App directory, which receives initial the JSON and renders a list.
<template> <ul class="uk-list uk-list-divider"> <li v-if="json" v-for="item in json"> <input type="checkbox" class="uk-checkbox" :checked="item.done" /> {{ item.title }} </li> </ul> </template> <script> export default { name: "App", data() { return { json: {} } }, created() { this.json = json } } </script>
The result is a simple list of todos which was renderd by Vue.
In an upcomming post can I show how I use a MiddleWare for sending Ajax requests to an controller action. That can be used in the Vue app to add new todos or toggle the done states.