MessageЧастота использования в разработке очень высока, и ее можно расценивать какElement-UIБиблиотека компонентов относительно проста, а друзья, которые интересуют, могут обсудить его вместеMessageРеализация компонента
Какова функция компонента
Он часто используется для подсказок обратной связи после активных операций, таких как отображение подсказки об успехе или неудаче при отправке формы.
Как использовать компонент
this.$message('这是一条消息提示');
this.$message({
message: '恭喜你,这是一条成功消息',
type: 'success'
});
Идеи дизайна компонентов
Messageвызываютсяthis.$messageсделать вызов, передав различныеoptionsУправление стилем и содержимым компонентов, отображениеhtmlдинамически вставляется вdocumentв и вdurationПосле удаления отображение компонента проходитvueДоступ к экземпляру и управление им.
Общая структура компонента разделена на часть отображения и часть управления.
- Часть дисплея отделена от компонента отдельно, а логика отображения и пакет взаимодействия компонента обрабатываются централизованно.
- Контрольная часть должна выполнять
vueПример и отображение компонентов
Общий процесс выполнения
Vueв проекте
// 1.引入组件库
import ElementUI from 'element-ui';
// 2.使用组件库
Vue.use(ElementUI);
Element-UIЛогика в библиотеке компонентов: каждый раз, когдаVue.useкогда вElement—UIсработает внутриElement-UIизinstallметод, затем зарегистрируйте компонент как глобальный компонент, поместите метод вVue.prototypeНа этот раз просто посмотрите на часть сообщения
// 1.引入Message对象
import Message from '../packages/message/index.js';
// 2. 定义 install函数,
const install = function(Vue, opts = {}) {
// 将组件遍历注册为全局组件,例如Button组件
components.forEach(component => {
Vue.component(component.name, component);
});
// 将方法放到Vue原型上
Vue.prototype.$message = Message;
};
После описанной выше двухэтапной обработки кромку можно передать прямо в проекте.this.$messageОтобразите управление компонентами, а затем продолжите изучениеElement-UIКак это обрабатывается внутри
часть дисплея
Во-первых, давайте посмотрим на компонентное содержимое части дисплея после удаленной версии.Код удаляет часть логического дисплея и плотно показывает основные функции.iconДругие функции можно просмотреть самостоятельно, что относительно просто
<template> <transition name="el-message-fade" @after-leave="handleAfterLeave"> <div class="el-message" :style="positionStyle" v-show="visible"> <slot> <p>{{ message }}</p> </slot> </div> </transition> </template><script type="text/javascript"> export default { data() { return { visible: false, message: '', duration: 3000, onClose: null, closed: false, verticalOffset: 20, timer: null }; },
computed: { positionStyle() { // 控制当前组件的显示位置 return { 'top':
${ this.verticalOffset }px}; } },смотреть: { // Мониторим закрытые изменения, при значении true уничтожаем компонент закрытый (новый вал) { если (новое значение) { this.visible = ложь; } } },
методы: { // Хук компонента перехода, выполняемый при срабатывании after-leave обработатьПослеОставления() { это.
el.parentNode.removeChild(this.$el);//удалить DOM компонента },
close() { this.closed = true; // 组件隐藏 if (typeof this.onClose === 'function') { this.onClose(this); } }, // 每次手动启动编译之后 设置其展示时间duration之后关闭 startTimer() { if (this.duration > 0) { this.timer = setTimeout(() => { if (!this.closed) { this.close(); } }, this.duration); } }}, mounted() { this.startTimer(); } }; </script>
скопировать код
<style> .el-message{ min-width: 280px; height: 42px; box-sizing: border-box; border-radius: 4px; border: 1px solid #ebeef5; position: fixed; left: 50%; top: 20px; transform: translateX(-50%); background-color: #edf2fc; transition: opacity .3s,transform .4s,top .4s; overflow: hidden; padding: 15px 15px 15px 20px; display: flex; align-items: center; background-color: #f0f9eb; border-color: #e1f3d8; } </style>
templateчасть
использовалVueОфициально упакованtransitionКомпонент не только обеспечивает хороший эффект перехода, но также предоставляет разработчикам подходящие крючки для управления, используемые в компонентах.after-leaveХук, когда компонент уничтожается, происходит уничтожение компонента иDOMудалениеvisibleИспользуется для управления отображением и уничтожением компонентов, вычисляемых свойствpositionStyleустановить размещение компонента,messageДля данных содержимого, отображаемых компонентом, вы можете понять роль этих переменных, вычисляемых свойств и методов.
scriptЧасть его можно понять, обратившись к аннотациям, а на два момента нужно обратить внимание
Первое, на что стоит обратить внимание, это хуки жизненного цикла.mountКогда вы это делаете, почему вы это делаете? Поскольку параметр el отсутствует, экземпляр не сразу перейдет к этапу компиляции, и вам нужно явно вызвать $mount, чтобы вручную запустить компиляцию.
Когда все еще нужно вниманиеcloseФункция делает две вещи, устанавливаяclosedЗначение запускает соответствующийwatch, закрывает компонент, если он существуетonCloseназывается метод, обратите внимание на этоonCloseОпределение функции определяется в разделе управления, что будет объяснено позже.
Секция управления
Пока ясноVueчерезthis.$messageОтображение компонента запущено, и содержимое компонента части дисплея также завершено.Теперь необходимо связать их через часть управления для достижения желаемой функции.
а такжеVueАссоциация относительно проста, просто определить метод и экспортировать его
const Message = options => {
// 逻辑编写....
}
export default Message;
принесите его и привяжите кVueВ прототипе опустите нерелевантный код
// 引入Message对象
import Message from '../packages/message/index.js';
// 将方法放到Vue原型上
Vue.prototype.$message = Message;
на этот раз черезthis.$messageможно вызвать, следующим шагом будетMessageФункция связана с компонентом и управляет презентационной частью.
Messageчто ядро должно делать
-
Скомпилируйте компонент, используйте рендеринг и вставьте в
bodyсередина -
в компоненте управления
visibleПеременные, запускающие отображение компонентов -
в компоненте управления
verticalOffsetПеременная, определяющая положение компонента при его отображении
Вручную запустите компиляцию компонента, получите его экземпляр для доступа к внутреннему
dataи вывод на страницу
// 1. 使用基础 Vue 构造器,创建一个“子类”
let MessageConstructor = Vue.extend(Main);
// 2. 组件实例, 可以通过instance访问 visible和verticalOffset
instance = new MessageConstructor({
data: options
});
весьMessageОстальная часть метода обеспечивает отказоустойчивость и надежную обработку.Общая краткая версия кода выглядит следующим образом.
let MessageConstructor = Vue.extend(Main);
let instance; // 当前组件
let instances = []; // 将所有的组件收集,用于位置的判断和销毁等
let seed = 1;
const Message = options => {
// 健壮性处理
if (Vue.prototype.$isServer) return;
options = options || {
message: 'content' + Date.now(),
onClose(message){
console.log('关闭时的回调函数, 参数为被关闭的 message 实例',message);
}
};
if (typeof options === 'string') {
options = {
message: options
};
}
// 关闭时的回调函数, 参数为被关闭的 message 实例
let userOnClose = options.onClose;
let id = 'message_' + seed++;
// 增加 onClose 方法,组件销毁时,在组件内部调用
options.onClose = function() {
Message.close(id, userOnClose);
};
// 组件实例
instance = new MessageConstructor({
data: options
});
instance.id = id; // 设置ID
instance.$mount(); // 因为不存在el选项,实例不会立即进入编译阶段,需要显示调用$mount 手动开启编译
document.body.appendChild(instance.$el); // 将Message 组件插入到body中
// 设置组件距离顶部的距离
let verticalOffset = options.offset || 20;
instances.forEach(item => {
verticalOffset += item.$el.offsetHeight + 16;
});
instance.verticalOffset = verticalOffset;
instance.visible = true; // 控制展示
instance.$el.style.zIndex = 99; // 控制层级
instances.push(instance);
return instance;
};
MessageПоддержка компонентовthis.$message.error('错了哦,这是一条错误消息');Звони и пользуйся, пока не поддерживается, код относительно простой и прямо на коде
// 为每个 type 定义了各自的方法,如 Message.success(options),可以直接调用
['success', 'warning', 'info', 'error'].forEach(type => {
Message[type] = options => {
if (typeof options === 'string') {
options = {
message: options
};
}
options.type = type;
return Message(options);
};
});
Он будет вызываться внутри компонента презентацииthis.onClose(this), устанавливаем внутри компонентаthis.visible=falseЗакройте всплывающее окно и удалите его соответствующийDOMструктура, но когда на странице отображается несколько компонентов, положение остальных компонентов необходимо изменить
onCloseфункция находится вMessageопределяется в функции
// 关闭时的回调函数, 参数为被关闭的 message 实例
let userOnClose = options.onClose;
// 增加 onClose 方法,组件销毁时,在组件内部调用
options.onClose = function() {
Message.close(id, userOnClose);
};
onCloseПоследний вызов функцииMessageстатический метод наclose
функцияMessage.closeНесколько вещей было сделано внутри
- Найдите компонент, который необходимо закрыть в массиве компонентов, отображаемых на странице и удалить его
- Пересчитать положение остальных компонентов
Message.close = function(id, userOnClose) {
let len = instances.length;
let index = -1;
for (let i = 0; i < len; i++) {
// 若是匹配到 则介绍此for循环
if (id === instances[i].id) {
index = i;
// 执行初始化组件时传入的onClose回调函数, 参数为被关闭的 message 实例
if (typeof userOnClose === 'function') {
userOnClose(instances[i]);
}
instances.splice(i, 1);
break;
}
}
console.log(`每个close ${len} -- ${index}`);
// 当只存在一个时组件展示或者没有匹配到需要销毁的组件时,不需要继续处理页面已有组件的展示位置
if (len <= 1 || index === -1 || index > instances.length - 1) return;
// 每一次销毁一个有效组件时,而页面还存在超过一个的组件,需要将页面展示的组件进行位置调整
const removedHeight = instances[index].$el.offsetHeight;
for (let i = index; i < len - 1 ; i++) {
let dom = instances[i].$el;
dom.style['top'] =
parseInt(dom.style['top'], 10) - removedHeight - 16 + 'px';
}
};
пока что базовая версияMessageОн завершен.Код компонента составляет менее 200 строк.Благодаря простому чтению и анализу исходного кода не так много очков знаний, но идея отличной упаковки компонента все еще стоит изучения и изучения.