LINUX.ORG.RU

Vue: как правильно делать переключение «драйвера» с сохранением реактивности?

 


0

1

Навалял на vue рыбу приложеньки https://puzrin.github.io/reflow_mock/. Теперь пытаюсь понять, как туда втулить поддержку нескольких девайсов.

Допустим, у меня есть полностью виртуальный и реальный девайсы, которые отдают температуру и т.п., a также имеют методы start/stop. Хочется чтобы при переключении на другой девайс все реактивные биндинги продолжили работать, просто забирая данные из другого источника.

Как это положено правильно делать в vue?

Пока в голову пришло сделать проксирующий объект:

const currentDriver = ref(defaultDriver)

// там где переключаем драйвер
currentDriver.value = driverInstance

// это выставляем приложеньке
export driver {
  temperature: computed(() => currentDriver.temperature.value),
  power: computed(() => currentDriver.power.value),
  start: () => currentDriver.start(),
  stop: () => currentDriver.stop()
}

Так годно или есть более кошерные варианты?

★★★★★

кошерно использовать для фронта вебкомпоненты из стандартов, а не сектантские колхозные компонентные системы на антипаттернах

Syncro ★★★★★
()
Ответ на: комментарий от static_lab

а какой вообще цимес использовать жс-фреймворк без его кнопачек? что-бы огородиться от других таких же кривеньких фреймворков на несовместимости разработок?

Syncro ★★★★★
()
Ответ на: комментарий от Syncro

По теме будет какой-нибудь комментарий? Ну или давай приведи аналогичный пример реактивности на веб-компонентах.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

для реакции на изменившиеся данные можно использовать, прокси, сеттеры, attributeChangedCallback, эвенты, специальные серверные протоколы, может быть что-то еще, что я сейчас уже не помню. В конце концов, если хочется тех же ошчушчений можно использовать и тот же RxJS.

Syncro ★★★★★
()
Ответ на: комментарий от Syncro

То есть заколхозить систему observable-observer, вместо того, чтобы использовать готовую? А RxJS, батенька, реализует push-модель, в отличие от используемой здесь pull-модели распространения изменений. То есть ошчушчения будут совсем другие. Учите матчасть.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

вот еще викреф какойт

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef

а готовые системы меняют на новые раз в год. Сколько там всего уже хранилок изобрели в рякте и их клонах для вуэ?

Штука в том что очень часто вам вообще не надо подобной штуки, потому что нет необходимости все «перерендеривать» грея юзеру ляжки. Это звучит как откровение, но можно просто изменить пропертю у элемента, а вопросы оптимального рендеринга возьмет на себя браузер.

Syncro ★★★★★
()
Последнее исправление: Syncro (всего исправлений: 2)
Ответ на: комментарий от Syncro

Слушай, ты вообще не в теме. Лучше помолчи и не позорься дальше.

static_lab ★★★★★
()

по состоянию на 21 год говорят, никак

в актуальной документации вышеупомянутая цитата присутствует до сих пор…

еще вон шина событий была, но её как-то выпиливают, похоже…

//мимокрокодил

aol ★★★★★
()
Последнее исправление: aol (всего исправлений: 1)

Я не очень вкурил, что там происходит, но, может, просто хранить список девайсов и текущий девайс в локальном/глобальном хранилище, и использовать текущий девайс во всех вью, где это нужно?

Можно дополнительно запилить composable типа useDevice, что-то вроде [current, all, select, add, remove, update] = useDevice(options), если, например, хочется иметь выбор, где именно хранить девайсы.

Кстати, в VueUse довольно немало готовых composables, на ресайз, например, там точно есть.

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

Ну так как ты предлагаешь, потом либо в компонентах путь до девайса выписывать, либо разбираться с реактивностью отдельных кусков класса.

У меня пока такой плагин вышел:

import Virtual from "./virtual"
import type { DeviceManager } from "./types"
import { computed, ref, type App } from "vue"

const virtual = new Virtual()

const drivers = {
  virtual
}

type DriverKey = keyof typeof drivers

const driverKey = ref<DriverKey>('virtual')

const device: DeviceManager = {
  // Driver proxy
  state: computed(() => drivers[driverKey.value].state.value),
  temperature: computed(() => drivers[driverKey.value].temperature.value),
  power: computed(() => drivers[driverKey.value].power.value),
  history: computed(() => drivers[driverKey.value].history.value),

  start: () => drivers[driverKey.value].start(),
  stop: () => drivers[driverKey.value].stop(),
  rawPower: (watts) => drivers[driverKey.value].rawPower(watts),

  // Control
  id: computed(() => driverKey.value),
  select: async (id: DriverKey) => {
    if (driverKey.value !== id) {
      // Detach old device first
      await drivers[driverKey.value as DriverKey].shutdown()
    }

    driverKey.value = id
    await drivers[id].attach()
  }
}

export default {
  install: (app: App) => {
    app.provide('device', device)
    device.select('virtual')
  }
}

Вроде рабочий, но ХЗ, не перемудрил ли.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

не перемудрил ли.

А разве reactive() на экземплярах классов не работает? Вроде должен. Оно тоже делает прокси для объекта, только автоматически.

Я бы попробовал сложить все устройства в хранилище pinia/vuex, добавить метод для выбора текущего устройства (который заодно будет делать attach/shutdown) и всё. Использовать текущее устройство в шаблонах или хуках.

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

А разве reactive() на экземплярах классов не работает? Вроде должен. Оно тоже делает прокси для объекта, только автоматически.

https://stackoverflow.com/a/67895251/1031804 там с this потом километры боли. По-моему оно того не стоит.

А можешь объяснить чем концептуально отличаются хранилища pinia от тех что в vueuse? Документация почему-то pinia советует. А в vueuse из коробки поддержка localStorage есть.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

чем концептуально отличаются хранилища pinia от тех что в vueuse

Pinia для централизованного управления реактивным состоянием (в памяти) — чтобы оно хранилось в одном месте, не размазываясь по рефам в куче компонентов, чтобы изменялось тоже контролируемо, через одно место.

(Как вариант, можно свалить всё состояние в самый верхний компонент и делать provide/inject, но это же будет помойка, причём не переиспользуемая.)

Можно, конечно, его и в localStorage сохранять, и на сервере, если хочется; а можно и не сохранять.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 3)
Ответ на: комментарий от Vit

там с this потом километры боли.

Там люди, похоже, специально себе яйца прищемили и радуются.

Nervous ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.