Как передать данные в экземпляр Vue, чтобы отражались последующие обновления? - PullRequest
0 голосов
/ 27 января 2020

Я пытаюсь динамически обновить Vue JS реквизит после загрузки представления и инициализации пользовательского. Я создаю собственный плагин Vue и использую опоры для передачи параметров, один из которых - объект, который мне нужен для динамического обновления значения, переданного после загрузки компонента, например:

<div id="app">
  <script>
  var seedData = {
    percent: 50,
    name: 'Smith'
  }
  setInterval(() => {
    seedData = {
      percent: Math.random(),
      name: 'Smith'
    }
  }, 1000)
  </script>
  <offers :parent-data="seedData"></offers>
</div>
Vue.component('offers', {
  template: '<h1>Parent Data: {{ parentData.percent }}</h1>',
  props: {
    parentData: {
      default: () => ({
        percent: 0,
        name: 'John'
      }),
      type: Object
    },
  }
});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app'
});

Это загрузит начальное имя / значения из offersData, однако новые значения в setInterval не будут пропущены.

Я пытался добавить наблюдатель внутри моего пользовательского Плагин Vue, который загружается через <offers>, но, похоже, он тоже не работает:

watch: {
  parentData: function (newVal) {
    this.parentData = newVal
  }
}

ОБНОВЛЕНИЕ

Ниже приведена моя реализация:

Код Pen -> https://codepen.io/sts-ryan-holton/pen/VwYNzdZ

1 Ответ

0 голосов
/ 28 января 2020

Есть несколько проблем с вашим кодом

  1. Все внутри <div id="app"> обрабатывается Vue как шаблон и компилируется - см. документы

Если нет ни функции render, ни опции template, извлеченный из DOM HTML монтажный элемент DOM будет извлечен как шаблон. В этом случае следует использовать сборку Runtime + Compiler со значением Vue.

Включая тег <script> там неправильно. Просто попробуйте включить vue.js (отладочная сборка) вместо vue.min.js (минимизированная производственная сборка Vue), и вы увидите кучу ошибок (кстати, всегда полезно использовать отладочную сборку для разработки, поскольку она дает вам много полезные ошибки и предупреждения)

Тот факт, что он "как-то работает" в сборке prod (ie начальные значения показаны на странице), не означает, что он поддерживается ...

Так что внутри <div id="app"> находится шаблон для Vue. Как я уже говорил в комментариях, все данные, на которые ссылается шаблон, должны быть в контексте экземпляра Vue. Вы не можете передать некоторую глобальную переменную в реквизит. Поэтому перемещение <script> за пределы <div id="app"> не поможет

[Vue warn]: свойство или метод "seedData" не определен в экземпляре, но на него ссылаются во время рендеринга. Убедитесь, что это свойство является реактивным, либо в параметре данных, либо для компонентов на основе классов, инициализируя свойство.

Что вы можете сделать, это передать seedData объект в root Vue экземпляр, подобный этому:

       var vm = new Vue({
          el: '#app',
          data: {
            seedData: seedData
          } 
        });

Теперь ошибки исчезли, но изменения данных по-прежнему не отражаются Причина этого не Vue конкретная c. Это просто JavaScript. Объект передается по ссылке в JS. Посмотрите на этот код:

var a = { name: 'John' }
var b = a
a = { name: 'Smith' }
// b is still pointing to "John" object

Чтобы обойти это, не заменяйте весь объект. Просто измените его свойства (остерегайтесь Vue предупреждений о реактивности )

      setInterval(function() {
          seedData.name = 'John';
          seedData.percent = Math.random();
      }, 1000)

Всего решения:

Vue.component('offers', {
  template: '<h1>{{ parentData.name }}: {{ parentData.percent }}</h1>',
  props: {
    parentData: {
      default: () => ({
        percent: 0,
        name: 'John'
      }),
      type: Object
    },
  }
});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app',
  data: {
    seedData: seedData
  } 
});
<script>
	  var seedData = {
	    percent: 60,
	    name: 'Smith'
	  }
	  setInterval(function() {
	      seedData.name = 'John';
	      seedData.percent = Math.random();
	  }, 1000)
	</script>
	<div id="app">		
	  <offers :parent-data="seedData"></offers>
	</div>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...