thehighhomie
@thehighhomie

Vuex/Redux: грамотное хранение объектов из сторонней библиотеки?

Здравствуйте! Прошу вас дочитать вопрос до конца, он не короткий, но это по тому, что я постарался как можно понятнее описать проблему.

Я пишу сложное приложение на Vue.js + Vuex: работа с текстом, изображениями и другими графическими объектами на canvas'e, для этого еще использую библиотеку fabric.js.

Так как библиотека fabric.js не как не связана с Vue.js то реактивности в ней нет, и я использую для обновление элементов watch.

Так вот, вопрос в том, что я столкнулся с проблемой управления объектов fabric.js в других компонентах кроме как в том, где инициализируется fabric.js. Мой вопрос связан с хранилищем, не важно Vuex или Redux, правда с Redux я почти толком и не работал, но принцип думаю пойму.

В моем случае я использую библиотеку fabric.js, но это не имеет значения, так как всяких библиотек для работы с элементами много, но суть я постараюсь понятно донести затрагивая fabric.js.

Кратко о моей реализации вывода объектов:

В компоненте TheCanvas, в хуке mounted, инициализируется объект canvas (new fabric.Canvas) и вызывается метод render, где идет цикл по объектам из хранилища. Пример упрощен, я не пишу код, который не имеет отношения к вопросу и не хочу сделать простыню на 3к пикселей в высоту)

mounted () {
  this.canvas = new fabric.Canvas(this.$el, {
    selectionColor: 'rgba(0, 112, 224, 0.02)',
    selectionBorderColor: 'rgba(0, 112, 224, 0.3)'
  })

  this.render(this.elems)
},

methods: {
  render (elems) {
      elems.forEach(elem => {
        if (elem.type === 'image') {
          fabric.Image.fromURL(elem.url, imgObj => {
            imgObj.set(elem.attrs)
            this.canvas.add(imgObj)
          })
        } else if (elem.type === 'text') {
          const textObj = new fabric.Textbox(elem.content, elem.attrs)
          this.canvas.add(textObj)
        }
      })
    }
}


Новые объекты я добавляю в хранилище вручную, иначе их ни как не добавить, так как какую-либо информацию о объекте fabric, можно получить только после создания объекта через new fabric
// вызов мутации добавления нового элемента
this.addElem({
  type: 'image',
  url: urls.regular,
  attrs: {
    top,
    left
  }
})

// а вот сама мутация, очень простая
addElem (state, payload) {
  state.elems.push(payload)
}


И получается у меня такая структура объектов:
// пример с 2 типами элементов, очень просто.
store: {
  elems: [
    {
      type: 'image',
      url: 'someUrl',
      attrs: {
        top,
        left
      }
    },
    {
      type: 'text',
      content: 'Текст',
      attrs: {
        top: this.canvasSize.height / 2 - 14,
        left: this.canvasSize.width / 2 - 40,
        padding: 4,
        width: 80,
        fontFamily: 'Arial',
        fontSize: 24,
        textAlign: 'center'
      }
    }
  ]
}


Так вот, такой способ хранения объектов в хранилище вообще не рабочий, потому, что в других компонентах я не могу получить данные о объекте, такие как выделенный текст и стиль каждого символа, так как эти данные можно получить только методом объекта fabric, который создается к примеру как в рендере (код render'a выше):
const textObj = new fabric.Textbox(elem.content, elem.attrs)
  this.canvas.add(textObj)

  // и уже у объекта texObj я могу вызвать метод и получить нужные стили:
  textObj.getSelectionStyles()

  // или же установить новые стили для выделенных символов текста
  textObt.setSelectionStyles({ color: 'red' })


Подведу итоги:
Способ которым я добавляю объекты - не рабочий, хотя для большинства случаев годен.

У объекта созданного через вызов new fabric есть метод toJson , который возвращает json объекта.

Я думал добавлять в хранилище json объекта fabric (сам объект нельзя передать, иначе выдает ошибку maximum call stack...), но смысла от json я не вижу, ведь в других компонентах, где нужно получать информацию о конкретном объекте (к примеру как я писал выше со стилями: textObj.getSelectionStyles()) я не смогу обратиться к этому методу, потому, что при вызове метода toJson, у объекта фабрики, в json просто свойства попадают.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы