Vue элегантно проектирует компонент

внешний интерфейс Vue.js

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, а также будет с открытым исходным кодом.