2017-01-23 4 views
2

Я довольно новичок в Vue Framework. Я пытаюсь распространять изменения с родительского на дочерние, когда атрибуты добавляются или удаляются или, на более позднем этапе, обновляются вне компонента. В нижеприведенном фрагменте я пытаюсь написать компонент, который показывает приветственное сообщение на основе атрибута имени узла, который передается как свойство из родительского узла.vue JS не распространяется изменения от родителя к компоненту

Все работает нормально, если ожидалось, если узел содержит атрибут «имя» (в нижнем фрагменте комментария) при инициализации. Но если атрибут name добавлен более поздний этап выполнения (здесь для демонстрационной цели я добавил тайм-аут набора и применял). Компонент выдает ошибку, и изменения не отражаются. Я не уверен, как я могу распространять изменения для динамических атрибутов в компоненте, которые генерируются на основе других событий вне компонента.

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

Vue.component('greeting', { 
 
    template: '#treeContainer', 
 
    props: {'message':Object}, 
 
    watch:{ 
 
     'message': { 
 
      handler: function(val) { 
 
       console.log('###### changed'); 
 
      }, 
 
      deep: true 
 
     } 
 
    } 
 
}); 
 

 
var data = { 
 
    note: 'My Tree', 
 
    // name:"Hello World", 
 
    children: [ 
 
     { name: 'hello' }, 
 
     { name: 'wat' } 
 
    ] 
 
} 
 

 
function delayedUpdate() { 
 
    data.name='Changed World'; 
 
    console.log(JSON.stringify(data)); 
 
} 
 

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

 
setTimeout(function(){ delayedUpdate() ;}, 1000)
<script src="https://vuejs.org/js/vue.js"></script> 
 
<div id="app"> 
 
    <greeting :message="msg"></greeting> 
 
</div> 
 
<script type="text/x-template" id="treeContainer"> 
 
\t <h1>{{message.name}}</h1> 
 
</script>

Edit 1: @ ответ Крейга помогает мне распространять изменения, основанные на имени атрибута и с помощью вызова устанавливается на каждом из атрибута. Но что, если данные были сложными, а приветствие было основано на многих атрибутах узла. Здесь, в примере, я прошел простой пример, но в реальном мире виджет основан на множестве атрибутов, динамически отправленных с сервера, и каждый атрибут виджета отличается в зависимости от типа виджета. например «Добро пожаловать», {{message.name}}. Температура в {{message.location}} - {{message.temp}}. "и так далее. Поскольку атрибуты узла различаются, можно ли каким-либо образом обновить полное дерево, не пересекаясь по всему дереву в нашем коде javascript и вызове, заданном для каждого атрибута. Есть ли что-нибудь в среде VUE, которое может позаботиться об этом?

ответ

5

Vue не может обнаружить добавление свойств или удаления, если вы не используете метод set (см: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats), так что вам нужно сделать:

Vue.set(data, 'name', 'changed world') 

Вот JSFiddle: https://jsfiddle.net/f7ae2364/

EDIT

В вашем случае, я думаю, вам придется отказаться от просмотра prop и вместо этого пойти на event bus, если вы хотите избежать перемещения ваших данных.Итак, сначала вы создали глобальную шину для вашего компонента для прослушивания:

var bus = new Vue({}); 

Тогда при получении новых данных, которые вы $emit это событие на автобус с обновленным данным:

bus.$emit('data-updated', data); 

И слушать для этого события внутри компоненты (который может быть размещен внутри созданного крюка), обновить сообщение и заставить vue вновь вынести компонент (я использую ES6 здесь):

created(){ 
    bus.$on('data-updated', (message) => { 
    this.message = message; 
    this.$forceUpdate(); 
    }) 
} 

Вот JSFiddle: https://jsfiddle.net/9trhcjp4/

+0

Спасибо за обновление, что если данные были сложными, а приветствие было основано на многих атрибутах узла. Здесь, в примере, я прошел простой пример, но в реальном мире виджет основан на множестве атрибутов, динамически отправленных с сервера, и каждый атрибут виджета отличается в зависимости от типа виджета. например «Добро пожаловать», {{message.name}}. Температура в {{message.location}} - {{message.temp}}. "и так далее. Поскольку атрибуты узла различаются, можно ли каким-либо образом обновить полное дерево без прохождения по всему дереву и набора вызовов по каждому атрибуту. – Ajay

+0

Также ваш код не работает, если я добавляю data.name = 'Измененный мир' перед Vue .set (данные, 'name', 'changed world1'). Это означает, что объект уже обновлен за пределами области действия, а затем даже установленная операция не поможет при установке ее на том же ключе. Любые советы о том, как преодолеть эти ограничения? – Ajay

+0

Спасибо @craig. Решения работают без каких-либо сбоев. – Ajay

 Смежные вопросы

  • Нет связанных вопросов^_^