Серия статей о упакованных компонентах Vue
- Процесс производства компонентов для гибридных селекторов
- Пакет компонентов периода времени выбора заголовков на сегодняшний день
фон компонента
Реализовать каскадный компонент на основе прототипа продукта, см. демонстрацию ниже.
Существует множество сценариев применения, таких как: система фонового управления, туристическая система, рекламная система, маркетинговая система и т. д., которые сейчас популярны.
Vue
,React
,Anagular
Три основных фреймворка, давайте посмотрим, как их использоватьVue
выполнить
реализовать логику
Требования к функции проверки менеджера по продукту следующие:
- Согласно выбору основной классификации на уровень подклассификации, ограничения по уровню нет (по ширине горизонтальной доски пользовательского интерфейса подходит для многоуровневого, но не так много сцен с большой глубиной )
- Каждый уровень поддерживает весь выбор, в соответствии с дочерним может вывести выбор всех вариантов и выполнить операцию выбора над своим родителем.
- Выбранный уровень может отображать список результатов, работать с результатами и быстро очищать результаты.
- Количество символов в названии категории не ограничено.Название категории выбираемой области должно отображаться в центре этого элемента.Если длина слишком велика, оно будет отображаться на новой строке.
- Структура параметров результата упрощена, каждый пункт фиксируется на одной строке, и появляется в конце, если он слишком длинный.
...
Представитель слишком длинный, и все содержимое отображается при перемещении мыши вверх
идеи
По своей сути Vue.js состоит из «отзывчивой системы».
«Отзывчивый», идея разработки полностью отличается от Jquery.
«Реактивный» означает, что при изменении данных Vue уведомит об этом код, использующий эти данные. Например, данные используются при рендеринге представления, и при изменении данных представление автоматически обновляется.
По региональным даннымJSON
Видно, что его структура
[
{
"value": "中国",
"key": 1156,
"id": 1156,
"children": [
{
"value": "北京市",
"id": 10000,
"key": 10000,
"children": []
},
{
"value": "河北省",
"key": 200107,
"id": 200107,
"children": [
{
"value": "石家庄",
"key": 20010701,
"id": 20010701
},
{
"value": "唐山市",
"key": 20010702,
"id": 20010702,
"children": [
{
"value": "路南区",
"key": 2001070201,
"id": 2001070201,
"children": []
}
]
}
]
}
]
- Китай
- муниципалитет
- хх провинция
- хх город
- хх площадь
- хх город
- хх округ
- хх город
Компоненты данных-кандидатов
Это циклически вложенный объект данных, и вложенность компонентов, похоже, не соответствует требованиям продукта.Если вместо иерархии используется массив, кажется, проблема вложенности данных может быть решена.
array => level 1 -> level 2 -> level 3 -> level 4
уровень 1 => текущий, дети => уровень 2 (массив) уровень 2 => текущий, дети => уровень 3 (массив) ...
каждый
level
это целое,
- имеет титул
title
- Есть выбрать все Вычислить, все ли выбрано в данных
select
- подмножество совокупных данных
data
- в настоящее время выбрал
current
- отметить индекс массива текущего уровня
level
Сначала определите пустой массив для представления компонента
const array = []
Этот компонент можно расширить, обработав данные в формате массива, так как же обрабатывать данные? Не все компоненты отображаются при инициализации компонента, пользователю должно быть разрешено выбирать текущую категорию верхнего уровня.
Получите все категории верхнего уровня и создайте первый элемент
- название провинции =
- данные = высшая категория
- текущий = пустой
- level = 1
- select = false
array.push({title, select, data, current, level})
Добавляет элемент подмножества в этот массив при выборе категории верхнего уровня.
array.push({title, select, data, current, level})
...
И так далее
селектор результатов
получить результат выбора компонента, Вы можете отфильтровать атрибут проверки данных, чтобы получить, Вы можете использовать вычисляемые свойства Vue, чтобы узнать результаты в любое время.
Поле выбора результата может напрямую связывать выбранный компонент расчета для создания пользовательского интерфейса результата.
Концепция компонента
- главный компонент
- компонент макета
- опции
Селектор основных компонентов
Раньше отвечал за рамку компонента, левую и правую колонки,
Слева область выбора, справа область результата
Это базовый слой компонента, который предоставляет импортированные реквизиты унифицированным способом.数据
а экспортируемый выброс事件
Компоненты должны быть полностью настроены, поэтому внутренние параметры должны быть абстрагированы.
- область выбора
Более равномерно распределенное пространство, все в горизонтальном фиксированном пространстве, не может делать слишком много уровней, слишком узкое для отображения
Поскольку иерархию необходимо отображать циклически, извлеченная иерархия является компонентом макета, а компонент макета состоит из
标题
а также滚动的选择区域
сочинение
<Row>
<Col :span="col" v-for="(box, idx) in resource" :key="idx">
<select-item :title="box.title">
<select-box v-model="box.current" :data="box.data" :level="box.level" @on-child="pushChild" @on-select="selectAll" />
</select-item>
</Col>
</Row>
- Область результатов Отображается только при наличии выбора, отображается строка заголовка, область результатов может подсчитывать количество результатов, элемент выбора использует тег тега, поддерживает быстрое удаление и устанавливает вертикальную полосу прокрутки. Вы можете использовать компоненты макета, чтобы сохранить стиль в соответствии с выбранной областью,
<Col span="7" offset="1">
<select-item v-if="resultLen && transfer" title="已选" clear @on-clear="$emit('on-clear', {list: data})">
<div v-for="item in result" :key="item.id" class="c-pop-tip">
<Tag :name="item.value" closable class="c-tag-item" @on-close="handleClose">{{item.value}}</Tag>
</div>
</select-item>
</Col>
элемент компоновки
Чтобы быть совместимым с областью выбора и областью результатов, количество статистических данных должно управляться переключателем. граница, управление цветом пользовательского интерфейса
Выберите все кнопки состоянияCheckBox
Компонент поля ввода поиска с кнопкой поиска
абстрактный интерфейс кнопки очистки Пользовательский интерфейс абстрактной статистики
Поле выбора (подкомпонент)
Самый важный компонент это Варианты следует разделить на две категории,
- Во-первых, на этом уровне нет детей.
- Во-первых, на этом уровне есть дети.
Оценка состояния ветвей может быть реализована с помощью дисплея, но с использованиемCheckBox
Компонент, который сам имеет функцию изменения, если онv-model
Binding, его значение меняется, главное дерево будет уведомлено об этом обновлении,
Это для второго типа выше.На этом уровне нет дочернего элемента для выполнения его работы, его обновления, его родитель может вычислить полувыбранное состояние, или количество выборок может быть рассчитано у родителя, но если есть Child , здесь для ответа на все его подмножества также должно быть выбрано, если выбрано подмножество, выбор подмножества также выбран
В процессе разработки отношение изменения здесь очень сложное, и без графики оно не понятно.
-
мероприятие Изменения подмножества можно изменить, щелкнув строку, Выбранное подмножество также изменяет изменения данных
-
типографика пользовательского интерфейса
логика
двусторонняя привязка
Преимущество данных привязки v-модели: данные изменились внутренне, но также изменились на исходной стороне, пока они используются,
Конечно, есть и некоторые неудобства в использовании.
Какой реквизит реквизита используется для получения данных, импортированных реквизитом?value
...
props: {
value: {
type: Array
}
}
...
Set нельзя изменить внутри компонента, его можно передать родительскому компоненту только через событие
Какое имя метода используется для его передачи?input
(Многие люди не знают о новичках)
this.$emit('input', val)
Сборка необработанных данных Выбор компонентов иерархии
Во время инициализации создайте компоненты первого уровня.title
data
current
level
Предположим, что данные провинции и города jsoncityJson
Создайте первый уровень данных
const data = this.cityJson.map(ret => {
delete ret.children
return ret
})
Когда пользователь выбирает уровеньitem
Запускается, когда действие добавляет данные уровня
Когда пользователь выбирает уровеньitem
Запускается, когда действие добавляет данные уровня. Выбрать все данные на этом уровне.
выбрать все
selectAll ({level, check, cat}) {
let index = level - 2
let current = index > -1 ? this.resource[index].current : ''
cat && (current = cat)
this.$emit('on-select', {
check,
current,
list: this.data
})
}
Бросьте его в ссылку корневого компонента для обработки, в основном, чтобы зациклить атрибут проверки текущего уровня данных на true
Флажок All-Element - это щит не может выбрать, позвольте ему выбрать подкомпонент связи событий.
поиск
Существует две реализации поиска, одна из которых представляет собой обычную реализацию внешнего интерфейса, которая проверяет возможность регуляризации внешнего интерфейса и оптимизирует скорость цикла.
Другим решением является запрос результатов через фон и фильтрация данных в соответствии с результатами.Внутренние данные не могут быть использованы напрямую, потому что данные корня дерева уничтожены, и выбор не может быть рассчитан.Есть четкая функция в поиске.После галочки Выбрать текущий элемент перед поиском код такой
clearBox (level) {
let current
const index = level - 2
// 还原原来所有的data
if (index > -1) {
current = this.resource[index].current
this.pushChild({ level: index + 1, current })
} else this.resource[0].data = this.data
}
удалять
Логика очистки окна результатов относительно проста, если для атрибута проверки всех выбранных данных установлено значение false. Конечно, вы также можете использовать цикл, чтобы установить все это снова, но вам нужно использовать $set, чтобы обновить данные здесь.
<select-item
v-if="resultLen && transfer"
title="已选"
clear
@on-clear="$emit('on-clear', {list: data})">
<div
v-for="item in result"
:key="item.id"
class="c-pop-tip">
<Tag
:name="item.value"
closable
class="c-tag-item"
@on-close="handleClose">{{item.value}}</Tag>
</div>
</select-item>
События являются ключом к разработке компонентов, а реакция на события обрабатывается в указанном компоненте.
код
Вставьте весь исходный код, в нем неизбежно будут какие-то ссылочные файлы, если вы не можете использовать его напрямую, пожалуйста, не распыляйте его, потому что эта статья не для ручной партии, это у вас есть определенная основа и хотите улучшить свои навыки
Селектор основных компонентов
<template>
<div class="c-selecter">
<Row :gutter="12">
<Col span="16">
<Row>
<Col
:span="col"
v-for="(box, idx) in resource"
:key="idx">
<select-item :title="box.title">
<select-box
v-model="box.current"
:data="box.data"
:level="box.level"
@on-child="pushChild"
@on-select="selectAll" />
</select-item>
</Col>
</Row>
</Col>
<Col span="7" offset="1">
<select-item
v-if="resultLen && transfer"
title="已选"
clear
@on-clear="$emit('on-clear', {list: data})">
<div
v-for="item in result"
:key="item.id"
class="c-pop-tip">
<Tag
:name="item.value"
closable
class="c-tag-item"
@on-close="handleClose">{{item.value}}</Tag>
</div>
</select-item>
</Col>
</Row>
</div>
</template>
<script>
import SelectItem from './select-item.vue'
import SelectBox from './select-box.vue'
export default {
name: 'selecter',
components: { SelectItem, SelectBox },
props: {
value: {
type: Array
},
title: {
type: Array
},
data: {
type: Array
},
transfer: {
type: Boolean,
default: true
}
},
data () {
return {
resource: []
}
},
computed: {
col () {
return 24 / this.resource.length
},
result () {
return this.value
},
resultLen () {
return Boolean(this.value.length)
}
},
watch: {
data (nVal) {
if (nVal && nVal.length) this.updateResource()
else this.resource = []
}
},
methods: {
updateResource () {
this.resource = []
this.resource.push({
data: this.data,
current: '',
level: 1,
title: this.title[0]
})
},
handleClose (event, name) {
this.$emit('on-delete', {list: this.data, name})
},
selectAll ({level, check, cat}) {
let index = level - 2
let current = index > -1 ? this.resource[index].current : ''
cat && (current = cat)
this.$emit('on-select', {
check,
current,
list: this.data
})
},
pushChild (params) {
const {item, level} = params
const len = this.resource.length
if (level <= len - 1) {
this.resource.splice(level, len - level)
}
this.resource.push({
data: item.children,
current: '',
level: level + 1,
title: this.title[level] || item.value
})
this.resource[level - 1].current = item.value
}
},
created () {
this.updateResource()
}
}
</script>
<style lang="stylus" scoped>
@import "~assets/styles/mixin.styl"
.c-pop-tip
width 100%
.c-tag-item
width 90%
margin 8px 8px 0
padding 2px 6px
display block
font-size 14px
height 28px
>>>span.ivu-tag-text
$no-wrap()
width calc(100% - 22px)
display inline-block
>>>.ivu-icon-ios-close
top -8px
</style>
элемент компоновки
<template>
<div class="c-select-item">
<div class="c-header">
<span class="c-header-title">{{title}}</span>
<span class="c-header-clear" v-if="clear" @click="$emit('on-clear')">清空全部</span>
</div>
<div class="c-selecter-content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'selectItem',
props: {
title: {
type: String
},
clear: {
type: Boolean
}
}
}
</script>
<style lang="stylus" scoped>
@import "~assets/styles/mixin.styl"
.c-select-item
background-color #fff
border solid 1px #dee4f5
.c-header
padding 0 12px
height 34px
font-size 14px
color #333
border-bottom solid 1px #dee4f5
background-color #fafbfe
.c-header-title, .c-header-clear
height 34px
line-height 34px
vertical-align middle
.c-header-clear
color #598fe6
float right
cursor pointer
.c-selecter-content
$scroll()
height 246px
width 100%
padding-bottom 8px
</style>
Поле выбора (подкомпонента)
<template>
<div class="c-select-box">
<div class="c-check-all">
<div class="c-item-select c-cataract" @click="selectAll"></div>
<Checkbox class="c-check-item" v-model="all">全选</Checkbox>
</div>
<div v-for="item in data" :key="item.id">
<div v-if="item.children && item.children.length" :class="itemClasses(item)" @click="$emit('on-child', {item, level})">
<Checkbox v-model="item.check" :indeterminate="itemIndeterminate(item)"></Checkbox>
<span>{{item.value}}</span>
<Icon type="ios-arrow-forward" class="c-check-arrow" size="14" color="#c1c1c1" />
<span class="c-item-checkbox c-cataract" @click="selectItem(item)"></span>
</div>
<Checkbox v-else class="c-check-item" v-model="item.check">{{item.value}}</Checkbox>
</div>
</div>
</template>
<script>
const computeChild = (list, Vue) => {
list.forEach(item => {
if (item.children && item.children.length) {
const child = item.children
if (child.every(ret => ret.check)) Vue.$set(item, 'check', true)
else Vue.$set(item, 'check', false)
computeChild(child, Vue)
}
})
}
export default {
name: 'selectBox',
props: {
value: {
type: [String, Number]
},
data: {
type: Array
},
level: {
type: Number
}
},
computed: {
itemClasses () {
return item => {
const cls = ['c-check-item']
item.value === this.value && cls.push('active')
return cls
}
},
all () {
const len = this.data.filter(ret => ret.check).length
return this.data.length === len
}
},
methods: {
selectAll () {
this.$emit('on-select', {
check: !this.all,
level: this.level
})
},
selectItem (item) {
this.$emit('on-select', {
check: !item.check,
level: this.level,
cat: item.value
})
},
itemIndeterminate (child) {
const hasChild = (meta) => {
return meta.children.reduce((sum, item) => {
let foundChilds = []
if (item.check) sum.push(item)
if (item.children) foundChilds = hasChild(item)
return sum.concat(foundChilds)
}, [])
}
const some = hasChild(child).length > 0
const every = child.children && child.children.every(ret => ret.check)
return some && !every
}
},
watch: {
data: {
handler (nVal, oVal) {
computeChild(nVal, this)
},
deep: true
}
},
mounted () {
computeChild(this.data, this)
}
}
</script>
<style lang="stylus" scoped>
@import "~assets/styles/mixin.styl"
.c-cataract
display block
position absolute
top 0
left 0
z-index 8
cursor pointer
.c-check-all
width 100%
height 36px
position relative
z-index 9
&:hover
.c-check-item
background-color #f8f8f8
.c-item-select
width 100%
height 100%
.c-check-item
margin 0
padding 0 12px
display block
position relative
height 36px
line-height 36px
&:hover
background-color #f8f8f8
&.active
color #598fe6
background-color #f8f8f8
.c-check-arrow
color #598fe6 !important
.c-check-arrow
float right
margin-top 10px
.c-item-checkbox
width 36px
height 36px
.c-select-box >>>.ivu-checkbox-indeterminate
.ivu-checkbox-inner
background-color #6fb3fb
border-color #6fb3fb
</style>
Оптимизируйте опыт
-
Функция половинного выбора Категория, выбранная в подкатегории основной категории, но сокращенная до других основных категорий.Несмотря на то, что в поле результатов есть выбранные категории, подкатегория не может отображаться в поле для выбора.После запроса в сети, опыт ответа клиента не очень хорошо Хорошо, поэтому я изучил флажки
半选
Состояние на самом деле очень просто изменить.Пока логическое значение добавляется к вычисляемому атрибуту для отображения полувыборки, логическое значение является классификацией.data
Есть ли выбранный элементcheck = true
-
Текст в строке слишком длинный, а отображение новой строки оптимизировано Поскольку нет ограничений на количество слов в категории, вы не можете доверять пользователю, когда вы являетесь фронтендом, и вы не можете доверять данным, возвращаемым бэкендом, и вы не можете доверять продукт.Если продукт не столкнулся с проблемой функции ограничения слов, вы все с нетерпением ждете этого.Пользователь является обычным пользователем.
- Есть два способа решить проблему слишком длинного текста:
- Установите фиксированную ширину в текстовой области и отображайте ее, когда она превышает длину... (Если вы хотите отобразить все целиком, вы можете только увеличить функцию отображения, наведя указатель мыши)
- существует
item
высота строки не используетсяline-height
параметры, использоватьpadding
После выполнения верхнего и нижнего интервалов позвольте тексту переноситься автоматически (проблема в том, что центрирование значка с правой стороны увеличит количество слов, если слов слишком много).item
пункт, эстетика не такая однородная)
- Есть два способа решить проблему слишком длинного текста:
Сводка опыта
Многие новички во фронтенде общались с Vue в течение года или даже более двух лет, прежде чем использовать какelement ui
,iview
,vant
Базовая библиотека пользовательского интерфейса с открытым исходным кодом, но вы можете обнаружить, что они подходят только для реализации html-кодирования со ссылкой на диаграмму прототипа, но разделение бизнес-уровня, повторное использование логики и компонентный бизнес-уровень не учат нас, как начать.
Ядром трех популярных фреймворков является быстрая разработка компонентов, и мы просто накапливаем компоненты библиотеки пользовательского интерфейса на странице компонентов маршрутизации, очевидно, что это не та эффективная разработка, которую мы хотим. Объем проекта может достигать более 100 страниц, если компоненты не разделены, объем повторяющейся работы непредсказуем, а об эффективности и речи быть не может. Итак, как вы можете использовать Vue на более глубоком уровне, как автор?На самом деле, в библиотеке элементов пользовательского интерфейса с открытым исходным кодом реализация каждого компонента на самом деле реализована очень простым методом.Если вы хотите реализовать такую базовую библиотеку, вы найдете способ увидеть. Вы можете узнать много идей автора, посмотрев исходный код, так какие еще компоненты не могут быть реализованы?
Мастер открывает дверь, практика зависит от человека, и каждый является нашим учителем. Не знаю, согласны ли вы с...
Выше, добро пожаловать в Paizhuan ~
Добро пожаловать в мой репозиторий с открытым исходным кодом ГИТХАБ:xiejunping (Cabber) · GitHubQR-код WeChat: отсканируйте код, чтобы добавить друзей и завести друзей