Vue элегантно проектирует компонент
Этот компонент имеет открытый исходный кодnpm publish, может быть самостоятельнымnpm install km-grid, по просьбе друга выложеноgithub.
Показать результаты
Принципы дизайна
Примечание: несмотря на то, что появилось большое количество отличных фреймворков пользовательского интерфейса, таких как elementUI и iviewUI, они все еще не могут удовлетворить все потребности проекта с точки зрения бизнеса, функций и производительности.В настоящее время вы должны подумать о том, как разрабатывать компоненты, которые тебе идет.
дизайн компонентовНа самом деле этомодульдизайн. Я разделил его на 4 части:Дизайн пользовательского интерфейса,основные навыки,потребности развития бизнеса,представление. Ниже приведен пример высокопроизводительной таблицы, которую я разработал сам, чтобы проанализировать, как я элегантно проектирую компонент.
- Взаимодействие дизайна пользовательского интерфейсакак модульimport,exports, для поддержания единого экспорта. То есть единый стиль и цветовое соответствие, единое взаимодействие.
- основные навыкиТак же, как основная роль модулей. Основные функции должны быть гарантированы при совместимости с другими.
- расширение бизнесаЭто похоже на интеграцию между модулями, для которой требуются компоненты с низкой зависимостью, подключаемой интеграцией, высокой интеграцией и низкой связанностью.
- представлениеПринимать во внимание большие объемы данных или большие объемы вычислений иGUIПроблемы с производительностью, вызванные взаимным исключением потоков рендеринга.
Этапы реализации
Примечание. Разработка компонента начинается с основных функций.
1. Макет
Давайте сначала рассмотрим основные функции таблицы, в том числе: заголовок, столбец с серийным номером, столбец с множественным выбором, левый и правый фиксированные столбцы, итоговая строка;
Функция развития бизнеса: поиск по колонке.
Учитывая, что для левого и правого фиксированных столбцов требуется отдельный заголовок, строка поиска, содержимое, итоговая строка. возможноkm-gridразработаны, чтобы3отдельныйtable, каждый индивидуумtableявляется независимымkm-grid-item.
<div :class="cls" :style="tableStyles">
<km-grid-item v-if="fixedLeftCol&&fixedLeftCol.length" fixed="left" v-on="$listeners" :columns="fixedLeftCol" :header-styles="leftFixedHeaderStyles" :body-styles="leftFixedBodyStyles"></km-grid-item>
<km-grid-item v-on="$listeners" :columns="centerCol" :expandColumn="expandCol" :header-styles="headerStyles" :body-styles="bodyStyles"></km-grid-item>
<km-grid-item v-if="fixedRightCol&&fixedRightCol.length" fixed="right" v-on="$listeners" :columns="fixedRightCol" :header-styles="rightFixedHeaderStyles" :body-styles="rightFixedBodyStyles"></km-grid-item>
</div>
Таким образом, дизайн всего стола будет легким и лаконичным.
Как насчет дизайна одной таблицы?
Итак, как мне управлять другими компонентами из одного компонента?
Во-первых, когда km-grid-item смонтирован, отправьте текущий VueComponent:
mounted () {
this.dispatch("KmGrid", "on-km-grid-item-add", this);
}
Получить в км-сетке:
created () {
this.$on('on-km-grid-item-add', item => {
this.itemVms.push(item);
})
}
Затем запустите синхронизацию для управления всей таблицей в событии:
HandleBodyScroll (event) {
this.$refs.header.scrollLeft = event.target.scrollLeft
if (this.$parent.itemVms && this.$parent.itemVms.length > 0) {
this.$parent.itemVms.forEach(v => {
let scrollDom = v.$el.querySelectorAll('.km-grid-noscroll')[0]
if (scrollDom) {
scrollDom.scrollTop = event.target.scrollTop
}
})
}
}
2. Потребности в развитии бизнеса
Требования к развитию бизнеса включают: отображение различных кнопок в соответствии с данными строки, различное поведение, форматирование данных и динамическое отображение раскрывающихся списков строк.
1. Отображение различных кнопок в соответствии с данными строки
Преобразование требований в операции с данными заключается в том, чтобы сначала получить данные строки, отобразить различные кнопки в соответствии с данными строки, а затем написать настраиваемое поведение в бизнесе:
Сначала определите столбец и операцию:
{
title: '操作',
type: 'handle',
handle: [
{
type: 'edit'
},
{
type: 'warehouse',
icon: 'km-stock',
click: row => {
this.$refs.listpage.showList = false
this.$refs.WarehouseInfo.loadEntity(row.id)
}
}
],
width: 90,
align: 'left',
fixed: 'right'
}
Визуализация из данных строки:
showCustomOperate: {
warehouse: row => {
switch (row.type) {
case '4':
return true
default:
return false
}
}
}
RebuildTableDataByColOperate (columns, data) {
data.forEach(v => {
handles.forEach(handle => {
v['__' + handle.type] =
this.showCustomOperate[handle.type](v) || false
})
})
}
HandleIconClick (item, row) {
return item.click(row);
}
Благодаря этому методу интеграции компоненты не должны заботиться о бизнес-требованиях и могут автоматически настраивать настраиваемые кнопки и поведение операций, а подключаемая интеграция не влияет на обслуживание компонентов платформы.
2. Динамический рендеринг выпадающего списка
Сначала настройте в столбцах:
{
type: 'expand',
width: 50,
render: (h, params) => {
return h(inventoryControl, {
props: {
row: params.row
}
})
}
}
components: {
inventoryControl: () => import('@/view/main-components/inventoryControl.vue')
}
Затем динамически визуализируйте в соответствии с данными строки в tr элемента km-grid-item:
<div v-if="!fixed&&expandColumn.render" :class="cls+'-tr-expand'">
<div style="width:100%" v-if="row._clicked">
<td-render :row="row" :render="expandColumn.render"></td-render>
</div>
</div>
Благодаря этому методу интеграции компонентам не нужно заботиться о бизнес-требованиях и возвращать данные строки, чтобы предприятия могли взаимодействовать сами по себе, не загрязняя текущую DOM компонента и избыточную логику кода.
3. Форматирование данных
Форматирование данных — старомодный вопрос, например, мы можем отформатировать системные данные только таким методом:
GetTdData (row, col) {
if (col.enumData) {
let desc = (col.desc && row[col.desc(row)]) ? '(' + row[col.desc(row)] + ')' : ''
return col.desc ? col.enumData[row[col.key]] + desc : col.enumData[row[col.key]]
} else if (col.valueKey) {
return row[col.key] ? `[${row[col.key]}]${row[col.valueKey]}` : ''
} else if (['date', 'datetime', 'time'].includes(col.type)) {
const dateEnum = { date: 'yyyy-MM-dd', datetime: 'yyyy-MM-dd HH:mm:ss', time: 'HH:mm:ss' }
if (!row[col.key]) {
return ''
} else {
return formatDate(row[col.key], col.format || dateEnum[col.type])
}
} else if (col.bizType && ['price', 'amt', 'qty', 'rate'].includes(col.bizType)) {
const formatEnum = { price: 4, amt: 2, qty: 3, rate: 4 }
if (typeOf(row[col.key]) === 'null') {
return '-'
} else {
return parseFloat(row[col.key]).toFixed(col.format || formatEnum[col.bizType])
}
}
return row[col.key]
},
GetTotalData (col) {
if (!col.total) {
return ''
} else if (col.totalValue) {
return col.totalValue
} else if (col.bizType && ['price', 'qty', 'amt'].includes(col.bizType)) {
const formatEnum = { price: 4, qty: 3, amt: 4 }
return this.$parent.data.map(row => Number(row[col.key])).reduce((a, b) => a + b, 0).toFixed(col.format || formatEnum[col.bizType])
}
return ''
}
Эта конфигурация по умолчанию согласовывается между интерфейсом и сервером, и клиент находится вcolumnsПосле указания его можно развертывать упорядоченным образом.
Подводя итог, требование расширения состоит в том, чтобы поддерживать бизнес-функции с минимально возможной конфигурацией, автоматизацией, подключаемостью, отсутствием загрязнения компонентов, сокращением логики дополнительных компонентов и отсутствием вторжения кода.
3. Производительность
проверено,km-gridИмеет эффективную производительность и совместим с основными браузерами (ie11выше, в том числеie11). сравнил то же самоеiview-table,element-table,существует500Когда данные на уровне столбцов,km-gridЛучшая производительность, далеко за пределамиiview-table. Студенты могут напрямуюnpm install.
Дизайн API компонентов
1. опора
Имя свойства | тип недвижимости | описывать |
---|---|---|
data | Array | метаданные |
headerRowHeight | Number | высота головы |
rowHeight | Number | высота строки |
totalRowHeight | Number | Общая высота |
height | Number | указанная высота |
width | Number | указать ширину |
border | Boolean | Показать разделительную линию |
pageSize | Number | данные с разбивкой на страницы |
current | Number | данные с разбивкой на страницы |
draggable | Boolean | Можно ли перетаскивать ширину столбца |
clickAsync | Number | Загружается ли событие щелчка асинхронно |
2. События
название события | описывать |
---|---|
on-selection-change | Выбрать все, срабатывать при выборе радио |
on-row-click | нажмите |
on-row-dblclick | двойной щелчок |
on-sort-change | Сортировать |
Три, методы
имя метода | описывать |
---|---|
GetSelectRows | Получить проверенную строку |
ClearSelectRows | очистить ряд канавы |
GetCurrentRow | получить выбранную строку |
km-gridУпрощенная конструкция с использованиемv-on="$listeners"Бросай события вверх, так пишиkm-grid-itemизemitСобытия не нужно подбрасывать повторно, а для тех, которые нужно открывать внешнему мируAPI,km-gridзатем намеренно потребует открытьAPIписать наkm-gridв.
// public API so i Expose in km-grid
GetSelectRows () {
return this.itemVms[0].GetSelectRows()
},
// public API so i Expose in km-grid
ClearSelectRows () {
this.data.forEach(row => {
this.$set(row, '_checked', false)
})
},
// public API so i Expose in km-grid
GetCurrentRow () {
return this.data.find(row => row._clicked)
}
Редактируемая таблица двусторонней привязки
Теперь фронтенд становится все более и более бэкендом, от npm-хранилища до модульности и автоматизации, фронтенд больше не является фронтендом страниц рисования несколько лет назад. Больше внимания уделяется модульности компонентов и управлению «взаимодействием» между компонентами и платформой, а также платформой и бизнесом. Если вы хорошо понимаете отзывчивость VueComponent VUE, вы будете как утка в океане VUE, и у вас также будет собственное уникальное понимание объектно-ориентированного программирования.
В следующем выпуске я покажу, какkm-gridт. е. высокопроизводительный редактируемый двусторонний переплетtable, а также будет с открытым исходным кодом.