345  /  381

Создание нового компонента на основе существующего (клонирование)

Просмотров: 478 (Статистика ведётся с 06.02.2017)
Анна Кокина
Сложность урока:
4 уровень - сложно, требуется сосредоточится, внимание деталям и точному следованию инструкции.
1
2
3
4
5
Недоступно в редакциях:
Ограничений нет

Создание нового компонента на основе существующего

Бывает, что компонент подходит, но за исключением одного действия (например, нужно, чтобы при выборе смайла он вставлялся не как :smile:, а как [smile]) или же не подходит шаблон компонента по умолчанию. При этом остальная работа компонента устраивает (например, выборка данных из базы, действия, события).

В таком случае проще всего клонировать компонент и изменить в нем только то, что нужно.

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

Как модернизировать компонент (мутация)

Схема похожа на схему создания нового компонента. Глобальные компоненты располагаются в модуле ui в директории /modules/ui/install/js/ui/vue/components/. Компоненты, которые относятся к вашему модулю, вы можете располагать в любой директории /modules/<module>/install/js/.

Все компоненты должны быть в виде расширений СoreJS в новом формате.

Подробнее...

Клон компонента необходимо расположить в директории своего модуля /modules/<module>/install/js/<some_path>.

Клон должен быть в виде расширения СoreJS в новом формате. В общих чертах клон будет выглядеть следующим образом:

/some-component/config.php

/some-component/lang/<...>/config.php

/some-component/module-name.extension-path.some-component.js

Cодержимое файла config.php:

<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
{
   die();
}

return array(
   'js' => Array(
      '/bitrix/js/module-name/extension-path/some-component/module-name.extension-path.some-component.js',
   ),
   'rel' => array('module.source.component'),
   'skip_core' => true,
   'bundle_js' => 'your-bundle-name'
);

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

Содержимое файла module-name.extension-path.some-component.js:

(function(window)
{
   "use strict";

   /**
    * Module name	
    * Some Component Vue component 
    * Clone of module.source.component
    *
    * @package bitrix
    * @subpackage moduleName
    * @copyright 2001-2019 Bitrix
    */
   
   const BX = window.BX;

   BX.Vue.cloneComponent('bx-moduleName-someComponent', 'bx-source-component-name',
   {
		template: `
			<div class="some-component">
				{{ result }}
			</div>
		`
   });

})(window);

Синтаксис метода: BX.Vue.cloneComponent(id, sourceId, mutations), где:

  • id - идентификатор нового компонента
  • sourceId - идентификатор компонента, с которого будет снята копия
  • mutations - параметры, которые будут заменены в оригинальном компоненте

Подробнее о заменяемых параметрах (мутациях)

Параметры этого массива полностью совпадают с массивом params в момент создания компонента, все ключи описаны в документации Vue Основы компонентов Основы компонентов

Компоненты — это переиспользуемые экземпляры Vue со своим именем. В примере выше это <button-counter>. Его можно использовать как пользовательский тег внутри корневого экземпляра Vue, созданного с помощью new Vue.

Подробнее...
и Продвинутые компоненты. Регистрация компонентов

При регистрации компонента у него всегда будет имя. Именем компонента будет первый аргумент.

Имя, которое даётся компоненту, может зависеть от того, где планируется его использовать.
При использовании компонента непосредственно в DOM (в отличие от строковых
шаблонов или однофайловых компонентов), настоятельно рекомендуем следовать правилам W3C
для именования пользовательских тегов (все символы в нижнем регистре, должен содержаться
дефис). Это позволит избежать конфликтов с текущими и будущими HTML-элементами.

Подробнее...

В массиве mutations нужно указать только те ключи, которые требуется изменить.

Рассмотрим пример: пусть нужно заменить метод sendText в оригинальном компоненте. Тогда объект mutations будет выглядеть так:

{
	methods:
	{
		sendText()
		{
			...
		}
	}	
}	

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

Правила мутации применяются ко всему дереву параметров, таким как methods, params, template.

  • Мутация строковых значений

    Строковые значения могут быть заменены на новые с возможностью вставить предыдущий текст в текст нового. Для этого в новом тексте нужно указать название этого параметра со знаками номера по обе стороны от переменной. Например, это применимо для параметра template: чтобы в новом компоненте можно было использовать шаблон старого, добавьте в новый текст #PARENT_TEMPLATE#.

    Представим, что шаблон ранее имел вид:

    {
    	template: "<span>123</span>"
    }	
    

    Допустим, вы хотите использовать старый шаблон в своем новом шаблоне:

    {
    	template: "<div>#PARENT_TEMPLATE#</div>"
    }	
    

    Итоговой версткой после отрисовки компонента будет:

    <div><span>123</span></div>
    
  • Мутация объектов

    Объекты (такие как params, methods, computed) могут быть расширены или заменены новыми значениями.

    Кроме того, при замене уже существующих параметров в объектах есть возможность получить доступ к предыдущему значению, написав слово parent у названия ключа. При этом первую букву ключа нужно будет перевести в верхний регистр. Например, если было вычисляемое свойство dateText, то после его изменения к предыдущему значению можно обратиться, используя parentDateText.

    Рассмотрим пример замены метода. Допустим, есть метод sendText, который отправляет текст вышестоящему компоненту:

    {
    	methods:
    	{
    		sendText(text)
    		{
    			this.emit('send', text);
    		}
    	}	
    }	
    

    Вас устраивает работа метода, но вы хотите модифицировать текст перед отправкой:

    {
    	methods:
    	{
    		sendText(text)
    		{
    			// модифицируем текст
    			text = '['+text+']';
    			
    			// вызываем родительский метод но уже с другим текстом
    			this.parentSendText(text);
    		}
    	}	
    }	
    

    Рассмотрим пример замены вычисляемого свойства на примере локализаций.

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

    {
    	computed:
    	{
    		localize()
    		{
    			return BX.Vue.getFilteredPhrases('IM_MESSENGER_MESSAGE_');
    		},
    	},
    }
    

    Вам нужно добавить свои, не потеряв при этом оригинальные:

    {
    	computed:
    	{
    		localize()
    		{
    			return Object.assign({},
    				this.parentLocalize,
    				BX.Vue.getFilteredPhrases('IMOL_MESSAGE_')
    			);
    		},
    	},
    }	
    

    Важно! Этот метод отработает корректно, даже если в оригинальном компоненте не было локализаций, т.к. Object.assign пропустит объединение с undefined свойством.

Примечание: Все остальные значения будут заменены полностью на новые.

Пример клонирования

Пример использования предыдущих значений при клонировании



1
Курсы разработаны в компании «1С-Битрикс»

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии