Просмотров: 1322 (Статистика ведётся с 06.02.2017)
Сложность урока:
4 уровень - сложно, требуется сосредоточится, внимание деталям и точному следованию инструкции.
5
Недоступно в редакциях:
Ограничений нет
|
Кастомизация компонентов партнерами |
Если перед вами стоит задача не создать новый интерфейс, а внести правки в уже существующий, вам необходимо использовать данный метод.
Техника повторяет технику клонирования, но за одним исключением - вызов метода BX.Vue.mutateComponent
изменит уже существующий компонент, а не создаст его копию.
Важно! Вы изменяете оригинальный компонент. Это значит, что все другие компоненты, использующие его, будут также изменены. Хотя мы и стараемся соблюдать обратную совместимость везде, где это возможно, вам необходимо проверять свои мутации после обновлений продукта (чтобы убедиться, что компонент продолжает работать так, как вы предполагали).
Как модернизировать компонент (мутация)
Схема похожа на схему
клонирования компонента.
Бывает, что компонент подходит, но за исключением одного действия (например, нужно, чтобы при выборе смайла он вставлялся не как :smile:
, а как [smile]
) или же не подходит шаблон компонента по умолчанию. При этом остальная работа компонента устраивает (например, выборка данных из базы, действия, события).
В таком случае проще всего клонировать компонент и изменить в нем только то, что нужно.
Подробнее...
Модификатор компонента (мутатор) необходимо расположить в шаблоне сайта (в js файлах шаблона).
Содержимое файла модификатора:
BX.Vue.mutateComponent('bx-moduleName-someComponent',
{
template: `
<div class="some-component">
{{ result }}
</div>
`
});
Синтаксис метода: BX.Vue.mutateComponent(id, mutations)
, где:
- id - идентификатор компонента для модификации
- 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 до 10 в обратном порядке, в виде черного текста.
Модифицируем его, чтобы он выводил цифры в цвете в случайном порядке. Для четных будет красный цвет, а для нечетных - зеленый.
BX.Vue.mutateComponent('bx-digits',
{
computed:
{
preparedDigits()
{
return this.shuffleArray(this.digits)
}
},
methods:
{
shuffleArray(array)
{
for (let i = array.length - 1; i > 0; i--)
{
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
},
template: `
<div>
<template v-for="digit in preparedDigits">
<span v-if="digit % 2" style="color: green; padding: 0 5px;">{{digit}}</span>
<span v-else style="color: red; padding: 0 5px;">{{digit}}</span>
</template>
</div>
`
});
BX.Vue.component('bx-digits',
{
data()
{
return {
digits: [1,2,3,4,5,6,7,8,9,10]
}
},
computed:
{
preparedDigits()
{
return this.digits.reverse();
}
},
template: `
<div>
<span v-for="digit in preparedDigits" style="padding: 0 5px;">{{digit}}</span>
</div>
`
});
BX.Vue.create({
el: '#vue-application',
template: `
<div>
<div>Компонент после мутации</div>
<bx-digits/>
</div>
`
});
Компонент после мутации
1 6 7 3 10 4 2 8 5 9
|
Пример использования предыдущих значений при мутации
|
Базовый компонент выводил числа от 1 до 10 в обратном порядке, при клике на цифру она окрашивалась сначала в зеленый, потом в красный цвет.
Мутируем компонент, наследуя его предыдущее поведение, и внесем следующие коррективы:
- шаблон вывода обрамляется красной рамкой;
- при клике помимо изменения цвета и шрифта добавляется цвет для заднего фона.
BX.Vue.component('bx-digits',
{
data()
{
return {
digits: [1,2,3,4,5,6,7,8,9,10]
}
},
computed:
{
preparedDigits()
{
return this.digits.reverse();
}
},
methods:
{
changeColor(event)
{
if (event.target.style.color == "green")
{
event.target.style.color = "red";
}
else
{
event.target.style.color = "green";
}
}
},
template: `
<div>
<span v-for="digit in preparedDigits" @click="changeColor" style="padding: 0 5px; cursor: pointer">
{{digit}}
</span>
</div>
`
});
BX.Vue.mutateComponent('bx-digits',
{
computed:
{
// заменяем существующие в оригинале вычисляемое свойство
preparedDigits()
{
// получаем доступ к предыдущему состоянию свойства через this.parent<НазваниеСвойства>
let reverseDigit = [].concat(
this.parentPreparedDigits
);
// добавляем к отсортированным значениям цифру ноль в конец.
reverseDigit.push(0);
return reverseDigit;
}
},
methods:
{
// заменяем существующие в оригинале функцию
changeColor(event)
{
// оставляем предыдущее поведение
this.parentChangeColor(event);
// добавляем новое
if (event.target.style.color == "green")
{
event.target.style.backgroundColor = "red";
}
else
{
event.target.style.backgroundColor = "green";
}
}
},
template: `
<div style="border: 1px solid red">
#PARENT_TEMPLATE#
</div>
`
});
BX.Vue.create({
el: '#vue-application',
template: `
<div>
<div>Вывод компонента с новым поведением</div>
<bx-digits/>
</div>
`
});
|
2
Развернуть комментарии