предисловие
При инкапсуляции сторонних компонентов часто возникает проблема, как использовать сторонние компоненты через инкапсулированные компоненты.Attributes(Атрибуты),Events(настраиваемое событие),Methods(метод),Slots(слот).
Конечно, решить эту проблему несложно, решение ее обычными методами неизбежно приведет к нудной и монотонной работе, а код инкапсулированного компонента не очень читабелен.
В этой статье будут представлены три метода использования сторонних компонентов.Attributes(Атрибуты),Events(настраиваемое событие),Slots(слоты), что касается использования сторонних компонентовMethodsТехнику (метода) еще предстоит оптимизировать, поэтому ее называют трехзубым топором.
1. Используйте свойства сторонних компонентов
Компонент поля ввода el-input, который инкапсулирует elementUI, называется myInput.disabled
атрибут, чтобы отключить поле ввода, как этого добиться? обычные школьники так делают
//myInput.vue
<template>
<div>
<el-input v-model="inputVal" :disabled="disabled"></el-input>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false
}
},
computed: {
inputVal: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
}
}
}
}
</script>
Через некоторое время я добавлю другие свойства компонента el-input в компонент myInput. Компонент el-input имеет в общей сложности 27 мульти-свойств, так что мне делать? не только громоздкий, но и плохо читаемый. ,Можно использовать$attrs
Шаг за шагом, давайте сначала посмотримattrs
официальное определение .
$attrs
: содержит бездействие в родительской областиprop
Распознанные (и полученные) привязки атрибутов (кроме класса и стиля). Когда компонент не объявляет никакихprop
, все привязки родительской области (кроме класса и стиля) включены сюда, и к ним можно получить доступ черезv-bind="$attrs"
Пропустить внутренние компоненты
//myInput.vue
<template>
<div>
<el-input v-model="input" v-bind="$attrs"></el-input>
</div>
</template>
Этого недостаточно, мы должныinheritAttrs
параметры установлены наfalse
, почему, посмотримinheritAttrs
Официальное определение опциона ясно.
Привязки атрибутов родительской области, которые по умолчанию не считаются реквизитами, будут «отступать» и применяться к корневому элементу дочернего компонента как обычные атрибуты HTML. Это может не всегда вести себя так, как ожидается, при написании компонентов, которые обертывают целевой элемент или другой компонент. установив
inheritAttrs
дляfalse
, это поведение по умолчанию будет удалено. и через$attrs
Вы можете заставить эти атрибуты действовать, а можете передатьv-bind
Явно привязан к некорневым элементам. Примечание. Этот параметр не влияет на привязки классов и стилей.
Проще говоря, положитьinheritAttrs
Установить какfalse
, чтобы избежать добавления свойств, установленных для компонента myInput, в div корневого элемента компонента myInput.
//myInput.vue
<template>
<div>
<el-input v-model="input" v-bind="$attrs"></el-input>
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: {
value: {
type: String,
default: '',
},
},
computed: {
inputVal: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
}
}
}
}
</script>
После этой настройки свойства компонента el-input можно использовать непосредственно в компоненте myInput, независимо от того, сколько свойств добавляется к последующему компоненту el-input.
2. Используйте пользовательские события сторонних компонентов
Если вы используете пользовательское событие для компонента el-input в компоненте myIpput, вашей первой реакцией может бытьthis.$emit
.
//myInput.vue
<template>
<div>
<el-input v-model="input" v-bind="$attrs" @blur="blur"></el-input>
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: {
value: {
type: String,
default: '',
},
},
computed: {
inputVal: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
}
}
},
methods: {
blur() {
this.$emit('blur')
}
}
}
</script>
<myInput v-model="value" @blur="handleBlur"></myInput>
В компоненте el-input есть 4 кастомных события, что не так уж и много. А вдруг вы встретите сторонние компоненты с большим количеством кастомных ивентов? Добавляете их по одному, что добавит кучу ненужных методов. использовать$listeners
Шаг за шагом, давайте сначала посмотрим$listeners
официальное определение .
$listeners
: содержит прослушиватель событий v-on в родительской области (без декоратора .native). Его можно передать внутренним компонентам через v-on="$listeners" .
//myInput.vue
<template>
<div>
<el-input v-model="input" v-bind="$attrs" v-on="$listeners"></el-input>
</div>
</template>
Затем добавьте компонент el-input в компонент myInput.v-on="$listeners"
, вы можете использовать пользовательские события компонента el-input в компоненте myInput.
3. Слоты для использования сторонних компонентов
Что, если слот, определенный в компоненте el-input, используется в компоненте myIpput? В этом методе не так много хитростей: сколько слотов определено сторонними компонентами, нужно использовать при инкапсуляцииslot
Этикетка раскрыта. Например, чтобы открыть слот префикса в компоненте el-input, код выглядит следующим образом:
//myInput.vue
<template>
<div>
<el-input v-model="input" v-bind="$attrs" @blur="blur">
<template #prepend>
<slot name="prepend"></slot>
</template>
</el-input>
</div>
</template>
В-четвертых, использование сторонних компонентов
использоватьref
Для этого сначала добавьте компонент el-input в компонент myInput.ref="elInput"
Атрибуты,
//myInput.vue
<template>
<div>
<el-input ref="elInput></el-input>
</div>
</template>
<script>
export default {
mounted(){
this.elInput = this.$refs.elInput;
}
}
</script>
Здесь следует обратить внимание на родительский и дочерний компоненты.mounted
Время выполнения компонента el-input, поскольку общий компонент el-input вводится глобально и импортируется синхронно.mounted
будет лучше, чем компонент myInputmounted
Сначала выполнить, чтобы его можно было выполнить в компоненте myInput.mounted
средняя ручкаthis.$refs.elInput
Назначается компоненту myInputthis
Один ресурс включен.
То, как компонент myInput использует компонент el-input, делится на две ситуации, связанные с введением компонента myInput.
Если компонент myInput вводится синхронно
<template>
<div>
<myInput ref="myInput"></myInput>
</div>
</template>
<script>
import myInput from './myInput.vue';
export default {
data() {
return {
}
},
components: {
myInput,
},
mounted() {
//调用el-input组件的focus方法
this.$refs.myInput.elInput.focus();
}
}
</script>
Если компонент myInput вводится асинхронно
<template>
<div>
<myInput ref="myInput"></myInput>
</div>
</template>
<script>
export default {
data() {
return {
}
},
components: {
myInput: () => import('./myInput.vue')
},
mounted() {
//调用el-input组件的focus方法
setTimeout(() => {
this.$refs.myInput.elInput.focus();
})
}
}
</script>