Vue, Twig (PHP), and set initial value from server #9692
-
I work on a web app based on the PHP framework Symfony. All the templates are in Twig and most of the logic is in Twig syntax too. The project also uses jQuery. I wanted to progressively migrate from jQuery to Vue.js (maybe it’s a bad idea) but I face one big issue: some values are initialized by the server and are set in a script tag in the Twig template. This means I cannot extract the JS in a separate Vue file and compile it through webpack. Furthermore, I have to progressively migrate to Vue.js which means I cannot set a root div as suggested in many articles but I must create multiple Vue instances here and there. So I have 2 questions:
For the first question, I was think of something like this but it seems it does not exist in Vue: <input v-model="name = {{ name_from_server }}" type="text"> |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
I am currently doing something similar. My current approach is as follows: // I create my store globally, and pass the same instance to my vueApps.
// With this all instances share the same store state
const Pinia = createPinia()
const appElements = document.querySelectorAll('[data-vueapp]') //Change this to match your elements in Twig.
appElements.forEach((element) => {
// Here I currently just pass the id set on the wrapper element.
// You could add data attributes or if you want pass globally available variables set by your script
const app = createApp(App, { app: element.id }
app.use(Pinia)
app.mount(element)
}) I am not sure if this covers your usecase, but it has worked for me so far.. If you come up with a better approach please let me know. Here is an example of how I pass translations from TYPO3 (also a PHP Framework/CMS) to my app: <script>
var TRANSLATIONS = {
titles: {
categories: '<f:translate key="titles.categories"/>',
plot: "{f:translate(key: 'titles.plot')}",
filters: "{f:translate(key: 'titles.filters')}",
list: "{f:translate(key: 'titles.list')}",
compare: "{f:translate(key: 'titles.compare')}",
torqueDiagram: "{f:translate(key: 'titles.torqueDiagram')}",
}
</script> I currently use this workaround in typescript to declare which data is already set globally. This could be done in a better way tho: declare const TRANSLATIONS: Translations; |
Beta Was this translation helpful? Give feedback.
-
Thanks for your answer @domialbrecht. The only inconvenient I see of using Alpine or even Petite Vue is that all third-party Vue components are not necessarily compatible with them. So it requires additional efforts on my side. Declaring data in a script tag triggers no-undef eslint error in the Vue file, which is not convenient… I thought of declaring data in a div file as a data- property. I will continue my experiments. I also explore this page but it won’t really me transition to full Vue: https://ux.symfony.com/ |
Beta Was this translation helpful? Give feedback.
I am currently doing something similar. My current approach is as follows:
I am not sure if this covers your usecase, but it has worked …