Интеграция с Vue JS

Библиотека Webix поддерживает интеграцию с фреймворком Vue JS.

Ресурсы для интеграции Webix с Vue JS не входят в пакет библиотеки Webix. Их можно получить из репозитория на GitHub.

Обзор

Интеграция будет полезна в двух основных случаях:

  • есть Vue-приложение, в которое нужно добавить один или несколько компонентов (datatable, chart, spreadsheet и т.д.)
  • нужно использовать Vue-приложение внутри Webix UI (реактивные шаблоны, пользовательские формы и т.д.)

Использовать Vue.js как MVC-фреймворк для Webix-приложений не рекомендуется. Размеры Webix виджетов не подстраиваются под лейаут фреймворка, а исправление таких ошибок приведёт к бóльшим издержкам, при сравнительно небольших преимуществах.

Для создания веб-приложений на основе Webix рекомендуется использовать фреймворк Webix Jet. Он нативен для библиотеки и помогает организовать этапы разработки наиболее эффективным образом.

Для интеграции Vue+Webix предоставляются следующие инструменты:

При необходимости, можно создать пользовательский компонент, обернув компонент Webix в Vue-компонент.

Подключение файлов

Обратите внимание: данная интеграция не входит в состав библиотеки Webix. Необходимые исходники можно взять на GitHub или подключить через CDN.

Подключите файл Vue в раздел head HTML-страницы:

<script type="text/javascript" 
  src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

Затем подключите файлы Webix JS и CSS, например, из CDN:

<script type="text/javascript" src="//cdn.webix.com/edge/webix.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.webix.com/edge/webix.css">

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

<!--для использования компонента Webix в Vue-приложении-->
<script type="text/javascript" src="//cdn.webix.com/libs/vue/3/webix-ui.js"></script>
<!--для использования Vue-компонента в Webix-приложении-->
<script type="text/javascript" src="//cdn.webix.com/libs/vue/3/vue-view.js"></script>
<!--для использования готовых элементов управления Vue+Webix-->
<script type="text/javascript" 
  src="//cdn.webix.com/libs/vue/3/webix-controls.js"></script>

Создание Vue-приложения с компонентом Webix

При разработке масштабного приложения на Vue.js могут понадобиться инструменты для работы с большими объёмами данных. В этом случае data-компоненты Webix значительно упростят задачу.

Инициализация Webix view в Vue-приложении

Прежде всего, подключите необходимые исходные файлы.

Чтобы добавить компонент Webix в Vue-приложение, выполните следующие шаги:

1. Создайте Vue-приложение.
2. Используйте тег < webix-ui > внутри Vue-шаблона для создания компонента Webix.
3. Укажите объект с конфигурацией Webix UI внутри объекта data экземпляра Vue.
4. Привяжите атрибут "config" элемента < webix-ui > к объекту данных с конфигурацией UI через директиву v-bind.

Рассмотрим пример. У нас есть лейаут из двух столбцов. В первом столбце расположен view Calendar, во втором - view List с данными. Конфигурация лейаута описана в объекте "ui". Этот объект привязывается к атрибуту config элемента < webix-ui > в Vue-шаблоне:

const app = Vue.createApp({
  template: `
    <div style="width:400px; height: 350px;">
        <h3>1. Building UI</h3>
        <webix-ui :config='ui'/>
    </div>
  `,
  data() {
    return {
      ui: {
        cols: [
          {
            view: "calendar",
          },
          {
            view: "list",
            select: true,
            data,
          },
        ],
      },
    };
  }
});
 
app.component(...); // инициализация компонента webix-ui
 
app.mount("#demo1");

В браузере результат будет таким:

Related sample: Building UI

Привязка данных

Данные компонента Webix можно привязать к Vue-шаблону с помощью стандартной техники Vue: директивы v-bind.

В следующем примере добавим в Vue-приложение компонент Webix DataTable и кнопку, которая очищает данные в datatable по клику:

const app = Vue.createApp({
    template: `
      <div style="width:400px; height: 250px;">
          <h3>2. One way data binding,
              <button v-on:click="data=[]">Clear</button>
          </h3>
          <webix-ui :config='ui' v-bind:modelValue='data'/>
      </div>
    `,
    data() {
      return {
        data,
        ui: {
          view: "datatable", 
          autoheight: true, 
          select: "row",
          columns:[
              { 
                id: "value", 
                header: "Section Index" 
              },
              ...
          ]
        }
      };
    } 
});
 
app.component(...); // инициализация компонента webix-ui
 
app.mount("#demo2");

Элемент < webix-ui > получает конфигурацию datatable и загружается с соответствующими данными.

Кнопка Clear внутри шаблона отслеживает событие click через директиву v-on. При клике событие срабатывает и очищает данные в datatable.

А в браузере результат будет таким:

и после клика по кнопке Clear:

Related sample: One-way Data Binding

Детали реализации

Способ разбора входящего значения зависит от компонента. Компонент верхнего уровня в блоке webix-ui попытается вызвать метод parse/setValues/setValue, если он существует. Кроме того, для всех компонентов Webix в блоке будет вызвано событие "onValue", что позволяет задать пользовательский обработчик значения (подробнее в следующем примере).

Двусторонняя привязка данных

Двусторонняя привязка данных означает: изменения в Vue-компоненте автоматически отражаются в привязанном компоненте Webix, и наоборот. Для этого используется стандартная директива Vue v-model.

Например, создадим Vue-шаблон с элементом input и добавим элемент < webix-ui >, который отрисует лейаут Webix со Slider внутри. При изменении значения в input или в slider, оно обновится в обоих компонентах. Рассмотрим, как это реализуется в коде:

const app = Vue.createApp({
  template: `
    <div style="width:400px; height: 250px;">
      <h3>3. Two-way data binding, try to change <input v-model.number='result'></h3>
      <webix-ui :config='ui' v-model.number='result'/>
    </div>
  `,
  data() {
    return {
      result: 50,
      ui: {
        margin: 20,
        rows: [
          {
            view: "template",
            type: "header",
            template: "Webix UI",
          },
          {
            view: "slider",
            label: "Change me",
            labelWidth: 120,
            inputWidth: 300,
            value: 50,
            on: {
              onChange() {
                this.$scope.$emit("update:modelValue", this.getValue());
              },
              onValue(value) {
                this.setValue(value);
              },
            },
          },
        ],
      },
    };
  } 
});
 
app.component(...); // инициализация компонента webix-ui
 
app.mount("#demo3");

А в браузере результат будет таким:

Атрибут данных result привязан одновременно к элементам input и slider.

При изменении значения, привязанного через v-model, в Webix view срабатывает событие onValue. При изменении значения в view Slider, срабатывает его встроенное событие onChange, которое уведомляет Vue об изменении.

Объявление this.$scope внутри обработчика события onChange указывает на элемент < webix-ui >, то есть на Webix view как Vue-компонент.

Related sample: Two-way Data Binding

Создание Webix-приложения с Vue-шаблоном

Реактивный шаблон Vue можно использовать внутри Webix-приложения. Для этого добавлен специальный view:"vue". Этот view представляет Vue-шаблон, который работает как нативный компонент Webix.

Для использования достаточно подключить соответствующий JS-файл.

Рассмотрим следующий пример. У нас есть лейаут Webix с view List, и мы хотим отображать данные элемента в соответствующем шаблоне, в зависимости от выбранного элемента списка.

Код ниже показывает, как связать Webix List с Vue-шаблоном:

const list = {
  view: "list", 
  id: "list", 
  select: true,
  template: "#value# (#size#)",
  data: [
      { id: 1, value: "Record 1", size: 92 },
      ...
  ]
};
 
const preview = {
    view: "vue", 
    id: "preview",
    template: `
      <div>
          <p>This part is rendered by VueJS, data from the list</p>
          <div v-if='value'>
              <p>Selected: </p>
              <p>Size: <input v-model='size'></p>
          </div>
      </div>
    `,
    data: {
      value: "",
      size: ""
    },
    watch: {
      size(value) {
          $$("list").updateItem($$("list").getSelectedId(), { size: value });
      }
    }
};
 
$$("preview").bind("list");

Принцип работы:

  • объект data получает значение из выбранного элемента List
  • свойство watch отслеживает изменения size внутри Vue-компонента и обновляет данные в списке

А в браузере результат будет таким:

Related sample: view:"vue" in a Webix App

Создание пользовательского компонента Vue+Webix

Можно создать пользовательский компонент, обернув компонент Webix во Vue-компонент, и использовать его как нативный Vue-шаблон. Это удобно, когда один и тот же UI многократно используется в приложении: все необходимые данные хранятся вместе.

Например, у нас есть input и slider. Мы хотим, чтобы их значения обновлялись одновременно.

Прежде всего, подключите необходимый исходный файл.

Затем выполните следующие шаги:

1) зарегистрируйте глобальный Vue-компонент с помощью app.component(name,options):

Подробнее о регистрации компонентов см. документацию Vue.js.

Назовём наш пользовательский компонент "my-slider". Начальный код регистрации компонента выглядит так:

const app = Vue.createApp({ ... });
 
app.component("my-slider", {
  // параметры конфигурации компонента
});

2) укажите необходимые параметры конфигурации Vue для компонента

Полный список параметров приведён в Vue.js API.

Для нашего компонента Slider используются следующие параметры:

  • props - объявляет список/хэш атрибутов, принимающих данные от родительского компонента
  • template - строковый шаблон для разметки нового компонента
  • watch - отслеживает изменения данных в одном из привязанных компонентов и применяет необходимые обновления в другом
  • mounted - функция, вызываемая сразу после создания компонента
  • unmounted - функция, вызываемая после разрушения компонента

Полный код регистрации компонента выглядит так:

app.component("my-slider", {
  props: ["modelValue"],
  // всегда пустой div
  template: "<div></div>",
  watch: {
    // обновляет компонент при изменении привязанного значения
    value: {
      handler(value) {
        webix.$$(this.webixId).setValue(value);
      },
    },
  },
  mounted() {
    // инициализирует Webix Slider
    this.webixId = webix.ui({
      // container и scope обязательны, остальные свойства опциональны
      container: this.$el,
      $scope: this,
      view: "slider",
      value: this.modelValue,
    });
 
    // уведомляет Vue об изменении значения для двусторонней привязки данных
    $$(this.webixId).attachEvent("onChange", function() {
      var value = this.getValue();
      // здесь можно использовать пользовательское событие
      this.$scope.$emit("update:modelValue", value);
    });
  },
  // очистка памяти
  unmounted() {
    webix.$$(this.webixId).destructor();
  },
});

Функция mounted() создаёт новый экземпляр Webix Slider.

Функция unmounted() разрушит экземпляр Webix Slider, когда он больше не нужен.

3) используйте зарегистрированный компонент в шаблоне Vue как пользовательский элемент:

const app = Vue.createApp({
  template: `
  <div style='width:300px;'>
      <h3>Vue + Webix: Custom UI</h3>
      <my-slider v-model.number='progress' />
      <div><input type="text" v-model.number='progress' /></div>
  </div>
  `,
  data: {
    progress: 50,
  },
});
 
app.component("my-slider", { ... });
 
app.mount("#demo1");

Слайдер, созданный выше на основе Webix, помещается в шаблон Vue-компонента.

Атрибут данных "progress" привязан одновременно к slider и input. При изменении его значения, оба элемента управления обновятся.

Related sample: Vue+Webix Custom UI

Готовые контролы Webix Form

Если вы не хотите оборачивать компонент Webix в Vue-шаблон самостоятельно, воспользуйтесь готовым набором контролов Webix Form, обёрнутых в Vue. Доступные элементы управления:

  • < webix-text >
  • < webix-datepicker >
  • < webix-colorpicker >
  • < webix-slider >
  • < webix-select >
  • < webix-richselect >
  • < webix-combo >
  • < webix-multicombo >
  • < webix-radio >
  • < webix-segmented >
  • < webix-tabbar >
  • < webix-textarea >
  • < webix-checkbox >

Для использования встроенных контролов в Vue-приложении, подключите упомянутый выше файл:
webix-controls.js.

После этого, любой из обёрнутых в Vue элементов управления Webix можно использовать в приложении, как показано в коде ниже:

const app = Vue.createApp({
  template: `
    <div style='width:500px'>
        <fieldset>
            <legend>User</legend>
            <webix-text         label='First Name'  v-model.string='fname' />
            <webix-text         label='Last Name'   v-model.string='lname' />
            <webix-datepicker   label='Birthdate'   v-model.date='birthdate' />
            <webix-colorpicker  label='Color'       v-model.string='color' />
            <webix-slider       label='Level'       v-model.number='level' />
        </fieldset>  
    </div>
  `,
  data: {
    fname: "Reno",
    lname: "Abrams",
    birthdate: new Date(1992, 10, 24),
    color: "#aaaff0",
    level: 20,
  },
});
 
app.component(...) // регистрация контролов
 
app.mount("#demo1");

А в браузере результат будет таким:

Related sample: Vue+Webix Form Controls

Если вы хотите создать собственный пользовательский Vue-компонент с компонентом Webix внутри, см. раздел Создание пользовательского компонента Vue+Webix.

Наверх