Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 09.11.2022, 19:12
Аватар для ANAGAMA
Аспирант
Отправить личное сообщение для ANAGAMA Посмотреть профиль Найти все сообщения от ANAGAMA
 
Регистрация: 29.05.2013
Сообщений: 49

VUE 2 сортировка компонентов
Итак страница имеет
<div id="app">
<sort>
   <line uid="1"> бла бла бла — много html идет в  слот </line>
   <line uid="2">  бла бла бла — много html идет в  слот </line>
   <line uid="3"> бла бла бла — много html идет в  слот </line>
</sort>
</div>


В компоненте line кнопочка - наверх (вниз) по кнопочке улетает событие.
Родитель (sort) ловит событие и меняет местами компоненты

Вся эта колобаха генерится движком сайта. Вытаскивать все данные в Vue и там их сортить совсем не хочется.
Ответить с цитированием
  #2 (permalink)  
Старый 09.11.2022, 22:05
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,588

Это противоречит сути vue так-то. Именно отдельно данный и надо слать, не вижу проблем заменить этот мусор на json.

Но если оень хочется, то придётся ручками писать render функцию, ктоторая будет сортировать ноды упавшие в слот к <sort>
__________________
29375, 35
Ответить с цитированием
  #3 (permalink)  
Старый 09.11.2022, 23:29
Аватар для ANAGAMA
Аспирант
Отправить личное сообщение для ANAGAMA Посмотреть профиль Найти все сообщения от ANAGAMA
 
Регистрация: 29.05.2013
Сообщений: 49

Сообщение от Aetae Посмотреть сообщение
Это противоречит сути vue так-то. <sort>
Спасибо. В общем да, но все в этой жизни чему то противоречит.

Но локоть сильно близко. И вроде все дети есть ... и можно было бы их местами поменять...

Или забить на эту задачу (и сделать смену на сервере в общем то админка) или приклеить туда jQuery и на нем махнуть местами два слоя...
Ответить с цитированием
  #4 (permalink)  
Старый 09.11.2022, 23:38
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,588

Кстати ты не можешь называть компонент "line" (если конечно не пошаманишь с конфигом Vue), т.к. такой элемент есть среди стандартных.
__________________
29375, 35
Ответить с цитированием
  #5 (permalink)  
Старый 10.11.2022, 08:10
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Сообщение от ANAGAMA
или приклеить туда jQuery и на нем
А без jquery никак?
Поставить один элемент перед другим - одна строка.
elem1.before (elem2) // elem2 поставить перед elem1
Ответить с цитированием
  #6 (permalink)  
Старый 10.11.2022, 09:31
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,588

Можно вообще это всё обойти: использовать для sort - display:flex (row\coluum что надо) и проставлять детям order не трогая реальной разметки.)
__________________
29375, 35
Ответить с цитированием
  #7 (permalink)  
Старый 10.11.2022, 11:58
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,588

С render функцией это можно сделать примерно так:
<div id="app">
<v-sort>
   <v-line uid="1">1 бла бла бла — много html идет в слот </v-line>
   <v-line uid="2">2 бла бла бла — много html идет в слот </v-line>   
   <v-line uid="3">3 бла бла бла — много html идет в слот </v-line>
</v-sort>
</div>

<script src="https://unpkg.com/vue@2"></script>
<script>
function addListener(options, type, listener) {
  if (!options || !type || !listener)
    return;
  
  if (!options.listeners) 
    options.listeners = {};
  
  if (!options.listeners[type]) 
    options.listeners[type] = listener;
  else if (Array.isArray(options.listeners[type])) 
    options.listeners[type].push(listener);
  else 
    options.listeners[type] = [options.listeners[type], listener];
  
  return options;
}

Vue.component('v-sort', {
  data() {
    return {
      keyCounter: 0,
      events: ['up', 'down'],
      children: []
    }
  },
  render(h) {
    return h('div', this.children.map(
      ({vNode, key}) => h('div', { key }, [vNode])
    ));
  },
  created() {
    this.children = this.getChildren();
  },
  methods: {
    getNewKey() {
      return this.keyCounter++;
    },
    getChildren() {
      const vNodes = this.$slots.default?.filter(vNode => vNode.componentOptions);
      
      if (!vNodes?.length) 
        return [];

      return vNodes.map(vNode => {
        const key = this.getNewKey();
        
        this.events.forEach(event => addListener(
          vNode.componentOptions, 
          event, 
          (...args) => this[event](key, ...args)
        ));
        
        return {
          key,
          vNode
        };
      });
    },
    findIndexByKey(key) {
      return this.children.findIndex(child => key === child.key);
    },
    up(key) {
      const index = this.findIndexByKey(key);
      if (index < 1) return;
      this.children.splice(index - 1, 2, this.children[index], this.children[index - 1]);
    },
    down(key) {
      const index = this.findIndexByKey(key);
      if (index === -1 || index > this.children.length - 2) return;
      this.children.splice(index, 2, this.children[index + 1], this.children[index]); 
    }
  }
})

Vue.component('v-line', {
  template: `<p>
    <button @click="$emit('up')">up</button>
    <slot/>
    <button @click="$emit('down')">down</button>
  </p>`
});

new Vue().$mount('#app')
</script>


Конечно гораздо лучше было бы если бы не нужно было слушать события из подкомпонентов, а просто рисовать кнопки прямо из компонента sort.)
__________________
29375, 35

Последний раз редактировалось Aetae, 10.11.2022 в 12:03.
Ответить с цитированием
  #8 (permalink)  
Старый 10.11.2022, 18:35
Аватар для ANAGAMA
Аспирант
Отправить личное сообщение для ANAGAMA Посмотреть профиль Найти все сообщения от ANAGAMA
 
Регистрация: 29.05.2013
Сообщений: 49

Нереально круто!
В общем посмотрел я на твою колобаху и понял, мне проще переписать в стандартной модели ВУ. А вообще нереально круто.
Ответить с цитированием
  #9 (permalink)  
Старый 10.11.2022, 19:20
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,120

Aetae,
если я каким-то хитрым способом изменю порядок в this.children, что нужно сделать чтоб новые изменения вступили в силу?
Ответить с цитированием
  #10 (permalink)  
Старый 10.11.2022, 19:40
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Вот чем мне не нравятся все фрейворки, так это тем, что простейшие вещи (почесать левое ухо) надо делать хрен знает как (правой ногой через спину)
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Vue 2 и router 4 torsar Библиотеки/Тулкиты/Фреймворки 1 04.06.2022 23:43
что такое defineComponent (vue cli) fori Javascript под браузер 1 22.03.2021 20:46
Локальное подключение компонентов vue? Lodas Библиотеки/Тулкиты/Фреймворки 0 11.04.2020 22:42
Vue + Axios + PHP + MySQL Volun Библиотеки/Тулкиты/Фреймворки 13 03.04.2019 18:50
UI верстальщик. VUE + Semantic UI shelomar Работа 0 12.01.2018 15:40