Я передаю карту компоненту, а затем возвращаю новые значения и обновляю карту. Это запускает часы на карте, но переданные старые и новые значения совпадают.

Возможно ли в этом случае иметь часы, принимающие старые значения?

(function() {

const ui = {
setup() {
  const map = reactive(new Map([
    ['width', 800],
    ['height', 400]
  ]));

  function onCompUpdate(evt) {
    console.log(map.get('width'), map.get('height'), evt[0], evt[1]);
map.set('width', Number(evt[0]));
    map.set('height', Number(evt[1]));
  }
  
  watch(map, (n,o)=>{
  console.log(n.get('width'), n.get('height'), 
  o.get('width'), o.get('height'));
  });

  return { map, onCompUpdate };
  },
};

const vueApp = createApp(ui);

vueApp.component('base-input', {
props: ['some' ], emits: ['comp-update'],
setup(props, { emit }) {

  let chars = ref(Array.from(props.some.values()).join(','));

  function checkInput(val) {
    emit('comp-update', val.split(','));
    chars.value = val;
  }

  return { chars, checkInput };
},
template: `<input type="text" spellcheck="false" :value="chars"
input="checkInput($event.target.value)"/>`
});

vueApp.mount('#vue');

})();

HTML:

<div id="vue">
  <base-input :some="map" @comp-update="onCompUpdate($event)"></base-input>
</div>

Скрипка: https://jsfiddle.net/tfoller/sm28u7r0/35/

1
user1481126 9 Дек 2020 в 01:32

1 ответ

Лучший ответ

Это происходит потому, что ссылки на старое и новое одинаковы. Вот одно решение. Вместо того, чтобы смотреть ссылку напрямую, наблюдайте за распространением ссылки, которая действительно меняется. Это должно быть сделано внутри выражения функции, поскольку спред не является реактивным:

watch(() => [...map], (nArray, oArray)=>{
    const n = new Map(nArray);
    const o = new Map(oArray);
    console.log(n.get('width'), n.get('height'), o.get('width'), o.get('height'));
});

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

Вот ваша обновленная скрипка

2
shob 8 Дек 2020 в 23:35