Как передать переменную из ветки в vueJS (Symfony 2.8 и VueJS 2)

У меня есть приложение 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, потому что мне не придется делать дополнительные запросы.

Вы нашли решение ?

Benjamin Seche 25.06.2018 14:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
6 053
4

Ответы 4

вам необходимо добавить следующее в ваш файл .vue props: ['paymentMethods'], пожалуйста, перейдите по следующему URL-адресу для получения полной документации https://vuejs.org/v2/guide/components.html#Passing-Data-with-Props

Извините, я забыл написать, что в моем файле .vue уже определено свойство props. Я обновил свой вопрос.

Stefan Gramadnikov 21.03.2018 11:07

у вас установлен vue DevTools? если да, зайдите в корень и проверьте, что показывает paymentMethods. @StefanGramadnikov

Sari Yono 21.03.2018 14:03

Упс, удалите : из :paymentMethods, он должен быть просто paymentMethods

Sari Yono 21.03.2018 14:07

Пробовал оба способа, разница в том, что у : свойство динамическое, но в моем случае это не имеет значения.

Stefan Gramadnikov 22.03.2018 13:06

хорошо, когда вы используете: он будет думать, что это переменная vue.

Sari Yono 23.03.2018 19:17

Вероятно, опоздал на вечеринку, но если у кого-то такая же проблема, проблема здесь была в кожухе.

Реквизиты 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)

Другие вопросы по теме