Нет необходимости писать страницу со списком запросов | Уменьшите низкоуровневую повторяющуюся работу vue+iview

Vue.js iView

В группе я спрашивал есть ли стандартный заголовок для такой страницы.Некоторые называются стандартными CRUD страницами, а некоторые называются информационными страницами форм.Не знаю как они называются.Верхний запрос а нижний Это список Страница закончена, с помощью мантры Луо Юнхао: «Меньше глупостей, сначала смотрите на вещи».демонстрационный адрес

Список страниц, которые появляются часто

С тех пор, как я сменил работу в сентябре прошлого года, я участвовал в нескольких проектах, включая платформу BI данных, платформу визуализации, проект с большим экраном и вторичную разработку JIRA.Существуют различные типы и технологические стеки, и я многому научился.

  • Платформа BI на основе vue использует iview для создания фона,
  • Основываясь на реакции, я знаком с antDesign\umi\dva\bizcharts
  • На основе вторичной разработки fis3 + yog2 JIRA
  • Недавно мои коллеги из back-end дали мне три системы middle-end на основе vue-element-admin.

Сказав так много, я хочу выразить следующее:Страница со списком запросов появляется слишком часто«Будь то система BI, система визуализации или мидл-офисная система toB, что касается клиентских должностей, неизбежно разрабатывать много таких страниц списка запросов. Порога технических требований нет. , но это надо сделать, т.н.низкоуровневая повторяющаяся работа".

Итерация компонентов пагинации

В предыдущем проекте BI компонент подкачки был инкапсулирован с компонентами iview table и Page.Просто передайте заголовок, адрес API и условия запроса, и все готово., с помощью которого реализованы все списки с разбивкой на страницы.

Получив требование мидл-энд системы перед рефакторингом, она была разделена на три приложения, а бэкенд выдал три адреса проекта git на основе vue-element-admin, и грубо посмотрел на предыдущую систему, почти все каналы на слева. Щелчок на странице списка запросов, непосредственно представляя предыдущий компонент подкачки для разработки версии v0.1, спрос на v1.0 растет, поэтому я просто потратил два дня, чтобы инкапсулировать условия запроса вместе 😃.

Создать страницу со списком запросов за пять минут

Условия запроса обычноkey:valueВ виде, например, документа, выдаваемого бэкендом, показан на рисунке ниже.

Мы инкапсулируем условие запроса и список в компонент, условие запроса на самом деле является конфигурацией опции, компонентТри основных входных параметра, адрес интерфейса, конфигурация условия запроса, настраиваемый заголовок, в процессе разработки часто приходится создавать новый компонент .vue, вводить компонент списка запросов, писать входные параметры, а потом вводить необходимые инструменты и методы, что на самом деле очень громоздко.

Итак, мы сами написали инструмент генерации, заполнили входные параметры согласно документу, нажали экспорт, и код компонента vue был скопирован прямо в буфер обмена, и создан новый..vueфайл, затемctrl+vВот и все.

Адрес инструмента

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

  1. Стоимость обучения выше, чем сложность разработки
  2. Инструменты просты и не могут удовлетворить потребности бизнеса

Может ли такая простая мелочь удовлетворить потребности бизнеса? Достаточно ли типов входных параметров? Можно ли судить по авторитету? Как настроить заголовок?

Дизайн функций компонентов

Этот компонент также инкапсулирован в реальный процесс разработки.Различные бизнес-сценарии, опыт разработки и отзывы о тестировании могут сделать этот компонент более стабильным и удобным в использовании., мы также определили API только в итерации актуальной версии спроса по одной.

Давайте посмотрим, что делает компонент. Это очень просто. Компонент разделен на две части: верхняя часть — это условие запроса, а нижняя — таблица подкачки.

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

В основном во второй половине вы также можете использовать только компонент списка, давайте рассмотрим основные параметры пейджинга списка.urlадрес интерфейса, адрес интерфейса каждого списка должен быть другим, гибкая конфигурация;searchDataэто запрос условия,ColumnsЭто заголовок компонента формы iview.Очень выгодно быть на плечах гигантов.Подробнее см.Форма документации API для iviewОтображение столбцов можно настроить;allDateЭто хук, который может изменить результат, возвращаемый серверной частью, например решить, добавлять ли кнопку операции на основе разрешений.

Остальное - это операция предыдущей страницы, следующей страницы, переход и изменение количества страниц, и можно установить формат с задней частью.

К формату данных списка также предъявляются определенные требования.dataCountобщее число,tableDataДанные тела,Columnsзаголовок,pageSizeКоличество записей на странице, как указано ниже

{
	"code": 1,
	"msg": "",
	"data": {
		"dataCount": 444,
		"tableData": [{
			"id": 443,
			"order_no": "1016410719705984",
			"source": 10,
			"order_type": 1,
			"order_status": 1,
			"car_name": "奥迪 A6 2006款 1.8 手动"
		}, {
			"id": 443,
			"order_no": "1016410719705984",
			"source": 10,
			"order_type": 1,
			"order_status": 1,
			"car_name": "奥迪 A6 2006款 1.8 手动"
		}],
		"Columns": [{
			"key": "order_no",
			"title": "订单ID"
		}, {
			"key": "order_type",
			"title": "订单类型"
		}, {
			"key": "source",
			"title": "来源"
		}, {
			"key": "car_name",
			"title": "车型"
		}, {
			"key": "order_status",
			"title": "状态"
		}],
		"pageSize": 10
	}
}

Давайте еще раз рассмотрим функцию всего компонента.

  1. Компонент условия запроса указывается в виде файла конфигурации в соответствии с документом и отображается
  2. После входа пользователя условия запроса инкапсулируются и передаются компоненту подкачки списка.
  3. Разбивка на страницы отображает содержимое в соответствии с пользовательским заголовком и выполняет такие операции, как механический переход вверх и вниз по страницам, переходы и т. д.

Сказав это, каковыapiМожешь рассказать об этом?

формат данных и API

templateчасть

В дополнение к свойствам компонента, необходимо упомянутьbuttonsэтоsoltТеперь помимо кнопок поиска и сброса на страницу часто необходимо добавлять другие кнопки, самые распространенные такие как新建.

urlадрес интерфейса

Строковый тип, каждый список имеет свой отдельный адрес

apiTypeглобальный адрес

Строковый тип, который мы используем в ajaxaxios, если это проект микросервиса, будет несколько конфигураций доменных имен, поместитеaxiosПросто введите имя экземпляра , значение по умолчанию — http, и укажите на прототип vue в main.js.

// 引入微服务apis
import { http, OderApi, ReportApi} from '@/lib/apis.js'
Vue.prototype.$http = http            // 默认地址
Vue.prototype.$OderApi = OderApi      // 订单服务
Vue.prototype.$reportApi = ReportApi  // 报表服务
fromOptionКонфигурация формы

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

select: раскрывающийся элементdate-picker: дата начала-окончанияinput:Поле вводаselectAndInput: раскрывающийся список + ввод

select

{
  label:'沿途城市',     // 标签名称
  name:['cityId'],     // *入参名称  必须唯一
  type:'select',       // *元素类型  selectAndInput
  dataType:'arr',      // 数据格式    arr/json
  arrKey:{             // arr数组格式下为必填
    value:'city_id',
    key:'name'
  },
  value:'',            // *默认选中值
  options:{            // *element组件属性 
    data:[             // 列表数据 仅在select类型下可用
      {
        city_id:'',
        name:'全部'
      },
      {
        city_id:1001,
        name:'北京'
      },
      {
        city_id:1002,
        name:'上海'
      }
    ]
  }
},

Данные выпадающего меню поддерживают два формата: массив и объект соответственноarrа такжеjsonУказывает, что в будущем этот входной параметр может быть оптимизирован и оцениваться непосредственно по типу.dataTypeдляjsonКогда формат данных, рекомендуется использоватьjson, что может сократить операции обхода.

 options:{             // *element组件属性 
    data:[             // 列表数据 仅在select类型下可用
      {
       全部:'',
       北京:1001,
       上海:1002
      }
    ]
  }

date-picker

в использованииelementUIкомпонент даты ,optionsможно пройти вelementUIофициальные свойства компонента,typeВ настоящее время поддерживается толькоdaterange,Документация по выбору даты elementUI.

Примечание. Поскольку текущий проект основан наvue-element-admin, что не учитывается при инкапсуляции, верхняя часть результатаelementUIКомпонент формы , нижняя частьiviewUIКомпонент формы будет унифицирован позже.

{
    label:'操作时间',
    name:['start_time','end_time'],     // *入参名称2个
    type:'date-picker',
    value:'',
    options:{
        'value-format':"yyyy-MM-dd",
        type:"daterange"
    }
}

input

{
    label:'车牌号',
    name:['car_no'],    // *入参名称2个
    value:'',           // *默认值
    type:'input'
}

selectAndInput

{
    label: "ID",
    type: "selectAndInput",
    value: "",
    defaulType:"id",       // 默认选中的下拉项值
    name:                  // 下拉菜单数据
      {
        运单:'transport_order_id',
        主运单:'transport_order_main_id'
      },
    selectOption:{},       // 下拉框官网api设置
    inputOtions:{}         // 输入框官网api设置
}

Раньше, когда мы генерировали такие условия запроса, мы специально проверяли внутренний интерфейс. Имейте в виду, что интерфейс разработан как поле типа и поле идентификатора, что не способствует разделению на одно условие запроса.

// 错误类型入参实例
{
    type:'transport_order_id',
    id:'99234i88845'
}

// 正确入参实例
{
   transport_order_main_id:'99234i88845' 
}
// 或
{
   transport_order_id:'99234i88845' 
}
Columnsнастраиваемый заголовок

тип массива

использовалiviewКомпонент формы должен быть знакомДокументация.

[
    { key: "order_no", minWidth:200, fixed: 'left'},
    {
      key: "order_status",
      minWidth:90,
      render:(h, params) => {
          let text = this.matchType('order_status',params)
          return h('div',text)
      }
    },
    {
      key: "source",
      render:(h, params) => {
          let text = this.matchTypeArr('source',params)
          return h('div',text)
      }
    },
    {title: "操作", key: "action",align:'center', minWidth:200, fixed: 'right',
        render:(h, params) => {

          let setingBtn = h('Button', {
                    props: {
                        type: 'primary',
                        size: 'small'
                    },
                    on: {
                        click: () => {
                            this.showSet(params.row)
                        }
                    }
                }, '发运设置')


          let editBtn = h('Button', {
                    props: {
                        type: 'primary',
                        size: 'small'
                    },
                    style:{
                        marginLeft:'10px'
                    },
                    on: {
                        click: () => {
                          this.$router.push('/constExplorer/editorLine/' + params.row.id)
                        }
                    }
                }, '班车设置')

            return h('div',[setingBtn,editBtn])
        }
    }
]
allDateИзменить возвращаемый результат

тип функции

По сути, это функция-ловушка.Каждый раз, когда вы перелистываете страницы или выполняете поиск, получаете данные и вносите некоторые изменения, например, добавляя минимальную ширину к каждому столбцу или определяя, следует ли отображать кнопку операции в соответствии с разрешениями.

addWidth(data){

    // 列最小宽度
    data.data.Columns.forEach(item => {
        item.minWidth = 170
    })

    // 操作按钮权限判断
    if(_.get(this.powers, 'oderList')){
        data.data.Columns.push({title: "操作", key: "action"})
    }
}

Общий метод

В повседневной реальной разработке, помимо API, есть много операций, которые мы часто используем, например, выпадающее меню — это интерфейс, форматирование табличных данных и т. д. Давайте пройдемся по ним вместе, вставим код и улучшим нашу разработку. эффективность.

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

created(){

    this.$http.get('/mock/city.json').then(res => {

        // 城市列表 数组格式
        let formIndex = _.findIndex(this.form, ['name', ['cityid']]);
        this.form[formIndex].options.data = this.form[formIndex].options.data.concat(res.data)

          })
        //  城市列表 对象格式 
        let formIndex = _.findIndex(this.form, ['name', ['cityid']]);
        this.form[formIndex].options.data = Object.assign(this.form[formIndex].options.data,res.data)

          })

        },

форматирование данных столбца таблицыНапример, в таком сценарии код состояния хранится в условии запроса, и нам нужно отформатировать данные столбца таблицы в соответствии с данными в условии запроса.

Условия запроса

Возвращаемые данные столбца1или100В этом формате мы инкапсулируем два метода, форматируем их отдельно и оптимизируем позже в один метод.

// 表头格式
{
  key: "order_type",
  render:(h, params) => {
      let text = this.matchType('order_type',params)
      return h('div',text)
  }
},
{
  key: "source",
  render:(h, params) => {
      let text = this.matchTypeArr('source',params)
      return h('div',text)
  }
},

matchType(key,params){

  let formIndex = _.findIndex(this.form, ['name', [key]]);
  let formType = this.form[formIndex].options.data

  let text = _.findKey(formType, item => {
    return item == params.row[key]
  });

  return text
}

matchTypeArr(key,params){

  let formIndex = _.findIndex(this.form, ['name', [key]]);
  let formType = this.form[formIndex].options.data
  let keyName = this.form[formIndex].arrKey.value
  let text = _.find(formType, item => {
    return item[keyName] == params.row[key]
  });

  return text.name
}

кнопки разрешений

Некоторое управление разрешениями должно быть точным для кнопки.У нас есть специальный интерфейс для получения разрешений и сохранения их в хранилище, и судим по всем данным, отображать ли кнопку операции.

addWidth(data){
    // 操作按钮权限判断
    if(_.get(this.powers, 'oderList')){
        data.data.Columns.push({title: "操作", key: "action"})
    }
}

Список открытых вопросов

  • Получите раскрывающийся список элементов фильтра, а затем запросите интерфейс списка
  • Решение о формате данных в раскрывающемся меню
  • Инкапсуляция метода форматирования данных столбца
  • Суждение нескольких кнопок власти
  • Условие запроса Элемент конфигурации с одним типом даты

Демонстрационный адрес и исходный код

Облако кодаgit ee.com/hello job/fo...

демонстрационная формапривет job.git ee.IO/форма и список…

Визуальная генерацияпривет job.git ee.IO/форма и список…