Компонент с хорошей применимостью, у кого есть много настраиваемых элементов, а другая легко переопределить, чтобы продлить функцию
API компонента Vue состоит из трех частей — свойств, событий и слотов:
- реквизиты позволяют внешней среде передавать данные компоненту
- событие позволяет запускать побочные эффекты внешней среды изнутри компонента
- слот позволяет внешней среде объединять дополнительный контент в компоненте
prop
Компонент имеет свое собственное состояние.Когда никакие связанные порпы не переданы, он использует свое собственное состояние для завершения логики рендеринга и взаимодействия;когда компонент вызывается, если есть переданные связанные реквизиты, он передает управление и родительский компонент будет управлять своим поведением
Только значение входящего компонента
- Если компонент поддерживает двустороннюю привязку, вы можете использовать
v-modelПередайте этот параметр в компонент, чтобы уменьшить затраты памяти (в конце концов, официальный синтаксический сахар vue, белый цвет не нужен)
<my-component v-model="foo" />
- Если компонент может работать независимо и не зависит от родительского компонента, дайте этому значению имя
<component-no-sync :childNeed="foo" />
В компонент нужно передать много значений
Например, когда компонент имеет много элементов конфигурации и если элементы конфигурации не передаются для использования элементов по умолчанию внутри компонента, наш исходный родительский компонент записывается так:
<child-component :prop1="var1" :prop2="var2" :prop="var3" ... />
Фактически, его можно использовать непосредственно в родительском компоненте.v-bind={子组件props集合}
Однако, чтобы облегчить переопределение элементов внутренней конфигурации подкомпонентов, вы можете использовать объект для сбора конфигурации вместе, но этот подход не может использовать свойства для проверки каждого типа значения в объекте.
<child-component v-model="text" :setting="{color:'bule'}" />
// 子组件内部读取配置,通过扩展运算符替换掉默认配置
const setting ={
...defaultSetting,
...this.setting
}
вычисляемое свойство
вычисляемое свойство vue по умолчанию доступно только для чтения, вы можете предоставитьsetter. Он может оптимизировать логику компонента, который я пишу, подходит для случая, когда значение, обрабатываемое родительским компонентом, и значение, обрабатываемое дочерним компонентом, совпадают.
<template>
<el-select v-model="email">
<el-option
v-for="item in adminUserOptions"
:key="item.email"
:label="item.email"
:value="item.email"
/>
</el-select>
</template>
export default {
props: {
value: {}
},
computed: {
email: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
this.$emit('change', val)
}
}
}
}
гибкий реквизит
Мы часто видим отличные библиотеки компонентов, и входящее значение может быть либо строкой/числом, либо функцией.
НапримерElementUIизTableКомпоненты, когда вы хотите отобразить данные дерева, должны быть переданыrow-key. Посмотрите на его введение, чтобы узнать, насколько он гибкий:
row-keyРоль: данные строкиKey, чтобы оптимизироватьTableрендеринг; использованиеreserve-selectionЭто свойство требуется, когда используются данные функции и дерева отображения. Когда тип String, поддерживается многоуровневый доступ:user.info.id, но user.info[0].id не поддерживается, в этом случае используйтеFunction
Исходный код функции для обработки rowKey для генерации RowIdentity:
//https://github.com/ElemeFE/element/blob/dev/packages/table/src/util.js
export const getRowIdentity = (row, rowKey) => {
if (!row) throw new Error('row is required when get row identity')
// 行数据的key
if (typeof rowKey === 'string') {
if (rowKey.indexOf('.') < 0) {
return row[rowKey]
}
// 支持多层访问:user.info.id
let key = rowKey.split('.')
let current = row
for (let i = 0; i < key.length; i++) {
current = current[key[i]]
}
return current
// 通过函数自定义
// 我处理过父和子id可能相同的情况,只好通过Function自定义
// 不可以通过时间或者随机字符串生成ID
} else if (typeof rowKey === 'function') {
return rowKey.call(null, row)
}
}
Из-за изменчивости бизнес-сценариев дизайнеру компонента сложно рассмотреть его полностью, лучше спроектировать гибкие реквизиты и определить их сами разработчики.
разное
Когда в компонент переданы реквизиты, попробуйте подумать, может ли компонент реагировать на изменения реквизитов при изменении реквизитов. То есть с помощью реквизита, использовать ли вычисляемые свойства или смотреть значение реквизита.
мероприятие
emit/on
Читатели должны знать, как использовать emit/on, поэтому я кратко расскажу оv-modelа такжеsyncсинтаксический сахар, мы можем использовать эти синтаксические сахара, чтобы помочь нам написать краткий код (родительские компоненты могут писать меньше событий, которые прослушивают дочерние компоненты, например, вам не нужно писать @input)
v-model
Взгляните на пример кода ниже, чтобы понять это утверждение. v-model игнорирует начальное значение атрибутов value, checked и selected всех элементов формы и всегда использует данные экземпляра Vue в качестве источника данных. Вы должны объявить начальное значение в параметре данных компонента через JavaScript
<input v-model="searchText" />
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
/>
// 当把v-model用在组件上
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
Чтобы заставить его работать, внутри этого компонента<input>Обязательно: привяжите свой атрибут value к реквизиту с именем value. Когда его событие ввода запускается, новое значение выбрасывается через пользовательское событие ввода, то естьthis.$emit('input',changedValue)
пользовательская v-модель
Зачем настраивать v-модель компонента, ведь данные не соответствуют требованиям. Ваше входное значение не всегда может быть value , и ваше событие не всегда может быть входным.Документация
sync (синтаксический сахар двустороннего связывания)
Vue действительно удобен для разработчиков, с точки зрения разработчиков он значительно повышает эффективность разработки.
Замена двусторонней привязки событием, запускаемым в шаблоне update:myPropNamethis.$emit('update:title', newTitle), подробности см.Документация
Функция передана через реквизит
Изначально я хотел поместить его в часть prop, но лично я думаю, что это больше связано с emit/on.
Некоторые читатели могут спросить, почему события в дочернем компоненте не могут генерироваться и обрабатываться родительским компонентом? Затем передайте свойство, которое управляет дочерним компонентом.
Что я хочу сказать, это может быть, но это действительно хлопотно, но состояние внутри подкомпонента - полагаться на родительские компоненты.
Внутреннее состояние компонента, нужно ли его выставлять? Я не думаю, что это необходимо, состояние внутри компонента делает его внутри компонента
Но вы можете участвовать в поведении изменений состояния компонента, передав функцию (вы можете понимать это как хук). Например, очень полезная библиотека перетаскивания,Vue.DraggableУправляет поведением перетаскивания элемента.
Vue.DraggableВы можете передать метод перемещения, и давайте посмотрим, как он работает.
onDragMove(evt, originalEvent) {
const onMove = this.move;
// 如果没有传入move,那么返回true,可以移动
if (!onMove || !this.realList) {
return true;
}
const relatedContext = this.getRelatedContextFromMoveEvent(evt);
const draggedContext = this.context;
const futureIndex = this.computeFutureIndex(relatedContext, evt);
Object.assign(draggedContext, { futureIndex });
const sendEvt = Object.assign({}, evt, {
relatedContext,
draggedContext
});
// 组件行为由传入的move函数控制
return onMove(sendEvt, originalEvent);
}
Преимущество этого в том, что внутри компонента есть свободный набор работающей логики, но я могу вмешаться, передав функцию. Я не модифицировал внутреннее состояние компонента напрямую, а запускал его через функцию (можно назвать хуком), что удобно для отладки компонента и делает поведение компонента предсказуемым
Родительский компонент напрямую манипулирует дочерним компонентом.
Таких операций немного, но из-за сложности данных и операций, когда структура данных сложная и вложенность слишком глубокая, родительскому компоненту сложно тонко контролировать данные дочернего компонента
Поэтому, если вам нужно это сделать, укажите методы, которые подкомпоненты могут вызывать в документации для использования пользователями. Использование такого компонента более хлопотно, надо смотреть документацию, если документации нет, надо смотреть исходный код
ElementUIизtreeкомпонентыПредоставляет родительским компонентам множество методов для управления дочерними компонентами.
eg:this.$refs.tree.setCheckedKeys([]);
слот
HTML
<slot>elementЭто часть технологии веб-компонентов и заполнитель для пользовательских веб-компонентов.Слот в vue вдохновлен проектом спецификации веб-компонентов.Подробнее см.Документация
слот по умолчанию
Если вы можете использовать слот по умолчанию, не используйте именованный слот Я действительно не хочу использовать ваш компонент для просмотра имени вашего слота.
Раньше у нас был шаблон сайта с тремя слотами, шапкой, телом и футером, мне было очень неудобно его использовать, ничего страшного, кто знает, что использовать (может я стар, если компоненты не нужны, постарайтесь не заставить людей иметь затраты памяти).
запасной контент
Он предназначен для определения значения по умолчанию для слота в компоненте, оно будет отображаться только в том случае, если содержимое не предоставлено. Рекомендуется использовать слот и добавлять в него контент по умолчанию
Инкапсулируйте чужие компоненты
Иногда мы можем инкапсулировать чужие компоненты, что здесь настоятельно рекомендуется.v-bind="$attrs" 和 v-on="$listeners".vm.$attrs— это свойство, содержащее привязки свойств (кроме класса и стиля), которые не распознаются (и не получаются) как реквизиты в родительской области. Доступ к этим нераспознанным свойствам можно получить черезv-bind="$attrs"Передайте внутренний компонент. Неопознанные события могут быть пропущены черезv-on="$listeners"входящий
Например, допустим, я создаю свой компонент кнопкиmyButton, который инкапсулирует компонент el-button из element-ui (на самом деле ничего не делает), используя компонент<my-button />Когда вы можете использовать свойства EL-Button непосредственно в компоненте, они будут встроены в элемент El-Button.
<template>
<div>
<el-button v-bind="$attrs">导出</el-button>
<div>
</template>
// 父组件使用
<my-button type='primary' size='mini'/>
именование компонентов
Рекомендуется следоватьофициальное руководство vue, стоит посмотреть
Когда мы создаем компонент, мы обычно называем его запись index.vue , При импорте мы можем напрямую импортировать папку компонента.
Но с этим есть проблема, когда редактируешь несколько компонентов, все записи компонентов называютсяindex.vue, легко спутать
vscode, по-видимому, знает об этой проблеме, поэтому, когда файл с таким же именем открывается, он отображает имя папки рядом с именем файла.
Как это решить, мы можем рассматривать index.js как простую запись без какой-либо логики. отвечает только за импортcomponent-name-containerтак же какexport default component-name-container
my-app
└── src
└── components
└── component-name
├── component-name.css
├── component-name-container.vue
└── index.js
советы (личные предпочтения)
-
template, положить
<template>Элемент рассматривается как невидимый элемент-обертка, и для него используется v-if. Окончательный результат рендеринга не будет содержать<template>элемент - Если вы можете использовать вычисление для вычисления свойств, постарайтесь не использовать часы
- Слишком много v-if в шаблоне сделают ваш шаблон уродливым,
v-else-ifПостарайтесь не использовать его. Длинный список if else выглядит беспорядочно в шаблоне
Есть ли у вас уникальные навыки написания компонентов, дайте мне знать в разделе комментариев