У меня есть приложение Symfony 2.8, и я недавно интегрировал VueJs 2 в качестве своего внешнего фреймворка, потому что он дает большую гибкость. Мое приложение не является одностраничным, и я использую контроллеры Symfony для рендеринга представлений. Все виды заключены в базовый макет веточки:
<!DOCTYPE html>
<html lang = "{{ app.request.locale|split('_')[0] }}">
<head>
<!-- Required meta tags -->
<meta charset = "utf-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<div id = "app">
{% block body %} {% endblock %}
</div>
<script src = "{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src = "/js/fos_js_routes.js"></script>
<script type = "text/javascript" src = "{{ asset('build/vendor-bundle.js') }}"></script>
<script type = "text/javascript" src = "{{ asset('build/vue-bundle.js') }}"></script>
</body>
</html>
Я загружаю большую часть JS с помощью webpack, все мои компоненты vue и зависимости JS скомпилированы в vendor-bundle.js и vue-bundle.js. Мой экземпляр VueJs выглядит так:
import './components-dir/component.vue'
import './components-dir/component2.vue'
Vue.component('component', Component);
Vue.component('component2', Component2);
window.onload = function () {
new Vue({
el: '#app',
components: {}
});
};
Я хочу передать некоторые переменные php из контроллера в компоненты vuejs, но мне не удается заставить его работать.
Очень простой пример контроллера выглядит так:
/**
* @Route("/contract", name = "contract")
* @Method("GET")
*/
public function indexAction()
{
$paymentMethods = PaymentMethod::getChoices();
return $this->render('contracts/index.html.twig', [
'paymentMethods' => $serializer->normalize($paymentMethods, 'json'),
]);
}
Все html, css и js обрабатываются vueJs. Вид ветки выглядит так:
{% extends 'vue-base.html.twig' %}
{% block body %}
<contracts :paymentMethods = "{{paymentMethods | raw}}"></contracts>
{% endblock %}
Компонент contracts.vue выглядит так:
<template>
<div>
<p>Hi from component</p>
</div>
</template>
<script>
export default {
data() {
return {}
},
props: ['paymentMethods'],
mounted: function () {
console.info(this.paymentMethods)
}
}
</script>
<style>
</style>
How can I pass the php variables as props to vueJs ?
В приведенном выше примере я не получаю никаких ошибок, но свойство не передается vuejs. Журнал консоли печатает undefined.
Я хочу иметь возможность сделать это, потому что я не хочу иметь SPA, но я также хочу передать некоторые переменные из symfony в vue, потому что мне не придется делать дополнительные запросы.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


вам необходимо добавить следующее в ваш файл .vue props: ['paymentMethods'], пожалуйста, перейдите по следующему URL-адресу для получения полной документации https://vuejs.org/v2/guide/components.html#Passing-Data-with-Props
Извините, я забыл написать, что в моем файле .vue уже определено свойство props. Я обновил свой вопрос.
у вас установлен vue DevTools? если да, зайдите в корень и проверьте, что показывает paymentMethods. @StefanGramadnikov
Упс, удалите : из :paymentMethods, он должен быть просто paymentMethods
Пробовал оба способа, разница в том, что у : свойство динамическое, но в моем случае это не имеет значения.
хорошо, когда вы используете: он будет думать, что это переменная vue.
Вероятно, опоздал на вечеринку, но если у кого-то такая же проблема, проблема здесь была в кожухе.
Реквизиты CamelCased, такие как paymentMethods, преобразуются в регистр дефисов в html и могут использоваться следующим образом:
<contracts :payment-methods = "{{ paymentMethods | raw }}"></contracts>
Вместо передачи переменной Twig в качестве значения Vue attr:
<contracts :payment-methods = "{{ twigVar}}"></contracts>
вы можете визуализировать целиком, используя ветку:
<contracts {{ ':payment-methods = "' ~ twigVar ~ '"' }}></contracts>
Благодаря этому вы избежите конфликта разделителей между vue и twig.
Кроме того, поскольку значение поступает непосредственно из ветки, оно, вероятно, не изменится со временем, поскольку оно создается в бэкэнде, а не в каком-то vue-источнике, поэтому вам не нужно его связывать, просто передайте его как
<contracts payment-methods = "{{ twigVar}}"></contracts>
Самый простой способ передать переменные из twig в приложение Vue:
Ветка:
<div id = "app" data-foo = "{{ foo }}" data-bar = "{{ bar }}"></div>
JS:
import Vue from 'vue'
new Vue({
el: '#app',
data: {
foo: '',
bar: ''
},
template: '<div>foo = {{ foo }}</div><div>bar = {{ bar }}</div>',
beforeMount: function() {
this.foo = this.$el.attributes['data-foo'].value
this.bar = this.$el.attributes['data-bar'].value
}
})
Если вы хотите использовать компонент Vue, вы можете сделать это следующим образом:
Ветка:
<div id = "app" data-foo = "{{ foo }}" data-bar = "{{ bar }}"></div>
JS:
import Vue from 'vue'
import App from 'App'
new Vue({
el: '#app',
render(h) {
return h(App, {
props: {
foo: this.$el.attributes['data-foo'].value,
bar: this.$el.attributes['data-bar'].value,
}
})
}
})
App.vue:
<template>
<div>foo = {{ foo }}</div>
<div>bar = {{ bar }}</div>
</template>
<script>
export default {
props: ['foo', 'bar'],
}
</script>
Обратите внимание, если вы хотите передавать массивы, вы должны преобразовать их в формат json раньше:
Ветка:
<div id = "app" data-foo = "{{ foo|json_encode }}"></div>
а затем вы должны декодировать json:
JS:
this.foo = JSON.parse(this.$el.attributes['data-foo'].value)
Вы нашли решение ?