Vue - слушать изменения реквизита (объект), смотреть, не вызывая - PullRequest
0 голосов
/ 26 января 2019

У меня есть похожая проблема с этим: VueJs 2.0 - как прослушивать изменения `props` , но в моем случае я отправляю объект от родителя к потомку, также с передачей несколько раз, чтобы использовать преимущества ссылок на объекты в JS.

Есть пример, но работает нормально:

<div id="app">
  <child :myprop="myObj"></child>
  <button @click="text = 'Another text'">Change text</button>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    myObj: {
       id: null
    }
  },
  components: {
    'child' : {
      template: `<div>
      <p>{{ myprop.id }}</p>
      <select v-model="myprop.id">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>
      </div>`,
      props: ['myprop'],
      watch: { 
        'myprop.id': function(newVal, oldVal) { // watch it
          console.log('Prop changed: ', newVal, ' | was: ', oldVal)
        }
      }
    }
  }
});
</script>

https://jsfiddle.net/8hqwg6Ln/

В моем случае я устанавливаю v-model для select на "parentObj.id", а затем добавляю наблюдателя для этого. Цель состоит в том, чтобы изменить другое свойство parentObj после изменения идентификатора - пользователь выбирает идентификатор, после чего я ищу этот идентификатор в моем массиве и устанавливаю parentObj.price, который является v-моделью, для другого компонента (модифицированного ввода) на том же уровне, что и поле выбора ,

Когда я меняю привязку, наблюдатель не срабатывает. Если я добавлю @change с помощью своего пользовательского метода, он будет работать, но с задержкой (я вижу это в инструментах vue dev, нужно обновить, чтобы получить текущие данные), также он не работает для второго компонента ввода - он не видит изменяет parentObj.price.

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

Ответы [ 4 ]

0 голосов
/ 27 января 2019

Я проверил некоторые вещи и нашел ошибку и решение.Во-первых, у меня была ошибка внутри моего пользовательского ввода - это мой компонент, который использует cleave-vue внутри.У Cleave-vue есть v-модель, я также использовал v-модель в своем пользовательском компоненте, и это было неправильно - я должен использовать привязку значений с синхронизацией (например:: value.sync = "parentCost").

Второе: да, я должен создать значения локально, затем передать их потомкам и добавить наблюдателей.В наблюдателях я делаю дополнительные манипуляции, такие как parseInt / parseFloat и т. Д., И устанавливаю родительские данные.Теперь все работает отлично.Это дублирование некоторых данных, но я думаю, что это не большая проблема - я создаю «абстрактный» миксин, потому что у меня много похожих пользовательских компонентов, и каждый использует шаблон watchers / setters.Код чистый.

0 голосов
/ 26 января 2019

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

"text = 'Another text'"

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

"myObj = { id: 'Another text' }"

Полагаю, это то, что вы хотите.Затем он реагирует, текст меняется на 1, 2 или 3, когда вы выбираете, и на «Другой текст», когда вы нажимаете, и ваш наблюдатель запускает и регистрирует старое и новое значение

.
0 голосов
/ 27 января 2019

Сначала потребуется реквизит для родительского компонента и локальные данные для выбранной v-модели:

<select v-model="localid">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>

, а реквизиты и данные вашего дочернего компонента:

data() {
      return {
        localid:null
      }
    },
props: ['pid']

, если компонентопора изменена, и его родитель хочет знать это изменение, вы можете использовать модификатор .sync.Сначала обновите вашу опору в вашем компоненте.просмотрите ваши localid данные и затем обновите вашу pid опору новыми данными:

watch:{
     localid:function(){
     this.$emit('update:pid', this.localid)
    }
}

Теперь родители знают, что pid опора изменена, и данные вашего родительского компонента изменятся с новыми данными опоры.Ваш родительский компонент:

<div id="app">
  <child :pid="myObj.id"></child>
  <button @click="text = 'Another text'">Change text</button>
</div>

Дополнительная информация: https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier

0 голосов
/ 26 января 2019

попробуй вот так

{
  ...
  props: ['myprop'],
  watch: { 
    'myprop.id': {
      handler(newVal, oldVal) {
        console.log('Prop changed: ', newVal, ' | was: ', oldVal)
      },
      deep: true
    }
  ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...