Vue — Правильный способ изменить слоты перед рендерингом — Цель: добавить ключ группы перехода программно

#javascript #vue.js

#javascript #vue.js

Вопрос:

У меня есть компонент-оболочка, который является просто <transition-group> компонентом, принимающим содержимое через его слот по умолчанию. Содержимое, передаваемое через слот по умолчанию, представляет собой серию вторичных компонентов vue.

Поскольку элементы в группе перехода должны иметь ключ, как бы мне добавить ключ к элементам слота? Поскольку они разделены на слоты и не отображаются в цикле v-for, я думаю, что ключи нужно было бы добавить программно.

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

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

Мысли?

Мне также просто любопытно в целом, когда в жизненном цикле подходящее время для внесения изменений в узлы слота. И далее, это узел.укажите нужное место для применения уникального ключа? Какое свойство в узле slot является правильным для редактирования? (т.Е. в свойстве component data также задается ‘key’, когда ключ задается в цикле v-for)

Большое спасибо за любую информацию, которую вы можете предложить!

 Vue.component('wrapper-component', {
  render(h) {
    return h('transition-group', this.$slots.default)
  },
  
  // my attempt at providing a unique key for transition children is in created() hook below
  // this works on itital page load/rendering - but breaks when hot-reload refreshes my development site
  // uncomment created() hook to see my approach in action - works here on page reload, but does not hold up with hot-reload (i.e. once hot-reload refreshes, the transition items no longer have their unique keys)
  
/*  
  created() {
    this.$slots.default = this.$slots.default.map((node, index) => {
      node.key = `${node.tag}-${index}`
      return node
    })
  }
*/
  
});

Vue.component('child-item', {
  render(h) {
    return h('div', this.$slots.default)
  }
});

new Vue({
  el: "#app"
});  
 div {
 display: block;
 width: 100%;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <wrapper-component>
    <child-item>My Child 1</child-item>
    <child-item>My Child 2</child-item>
    <child-item>My Child 3</child-item>
    <child-item>My Child 4</child-item>
  </wrapper-component>
</div>  

Ответ №1:

Попробуйте добавить beforeUpdate перехват:

   beforeUpdate() {
    this.$slots.default = this.$slots.default.map((node, index) => {
      node.key = `${node.tag}-${index}`
      return node
    })
  }
  

Комментарии:

1. Я думаю, это было так просто. Мне нужно будет провести еще несколько тестов, чтобы знать наверняка, и логика необходима в перехватах created() и BeforeUpdate(), но пока все выглядит хорошо! Похоже на редактирование узла. ключ работает, поэтому, я думаю, я просто поверю, что это хороший способ выполнить то, что мне нужно. Забавно, как мой разум ожидает, что все будет сложно, а это не так! Большое спасибо за ваше понимание!