Heim >Web-Frontend >View.js >Wie die Vue3 Composition API Komponenten von Drittanbietern elegant kapselt
Wie kann man bei Komponenten von Drittanbietern die Funktionen elegant erweitern und gleichzeitig die ursprünglichen Funktionen der Komponenten von Drittanbietern (Requisiten, Ereignisse, Slots, Methoden) beibehalten?
Nehmen Sie den El-Input von Element Plus als Beispiel:
Es ist sehr wahrscheinlich, dass Sie schon einmal so gespielt haben, indem Sie eine MyInput-Komponente gekapselt und die Requisiten, Ereignisse, Slots und Methoden hinzugefügt haben, die Sie entsprechend Ihren eigenen verwenden möchten Schreiben Sie es noch einmal:
// MyInput.vue <template> <div class="my-input"> <el-input v-model="inputVal" :clearable="clearable" @clear="clear"> <template #prefix> <slot name="prefix"></slot> </template> <template #suffix> <slot name="suffix"></slot> </template> </el-input> </div> </template> <script setup> import { computed } from 'vue' const props = defineProps({ modelValue: { type: String, default: '' }, clearable: { type: Boolean, default: false } }) const emits = defineEmits(['update:modelValue', 'clear']) const inputVal = computed({ get: () => props.modelValue, set: (val) => { emits('update:modelValue', val) } }) const clear = () => { emits('clear') } </script>
Aber nach einiger Zeit ändern sich die Anforderungen und andere Funktionen der el-input-Komponente müssen zur MyInput-Komponente hinzugefügt werden. Eigenschaften, 5 Ereignisse und 4 Slots, was sollen wir tun? Das ist nicht nur umständlich, sondern hat auch eine schlechte Lesbarkeit.
In Vue2 können wir damit umgehen. Klicken Sie hier, um die Kapselung von Vue-Komponenten von Drittanbietern anzuzeigen.
Dieser Artikel soll Ihnen beim Wissenstransfer helfen und erkunden, wie Sie Vue3 CompositionAPI verwenden, um Komponenten von Drittanbietern elegant zu kapseln ~
in Vue2
$attrs: Enthält Attributbindungen (außer Klasse und Stil), die im übergeordneten Bereich nicht als Requisiten erkannt (und abgerufen) werden. Wenn eine Komponente keine Requisiten deklariert, werden alle übergeordneten Bereichsbindungen (außer Klasse und Stil) hier einbezogen, und interne Komponenten können über v-bind="$attrs"
$listeners: Included v- übergeben werden. auf dem Ereignis-Listener im übergeordneten Bereich (ohne .native-Modifikator). Es kann über v-on="$listeners"
und in Vue3
an interne Komponenten übergeben werden. $attrs: enthält Attributbindungen und Ereignisse im übergeordneten Bereich, die keine Komponenten-Requisiten oder benutzerdefinierten Ereignisse sind (einschließlich Klasse). , Stil und benutzerdefinierte Ereignisse) und interne Komponenten können über v-bind="$attrs" übergeben werden.
$listeners-Objekt wurde in Vue 3 entfernt. Ereignis-Listener sind jetzt Teil von $attrs.
Im be037f1db418a760eb29637b48c9d49b kann die Hilfsfunktion useAttrs $attrs abrufen.
//MyInput.vue <template> <div class="my-input"> <el-input v-bind="attrs"></el-input> </div> </template> <script setup> import { useAttrs } from 'vue' const attrs = useAttrs() </script>
Natürlich ist das nicht genug. Wenn Sie einfach so schreiben, funktionieren die von uns gebundenen Attribute (einschließlich Klasse und Stil) auch für das Stammelement (das obige Beispiel ist der Dom-Knoten mit class="my-input"). Um dieses Standardverhalten zu verhindern, müssen wir inheritAttrs auf false setzen.
Werfen wir einen Blick auf die Erklärung des Vue3-Dokuments zu inheritAttrs
Standardmäßig werden Attributbindungen im übergeordneten Bereich, die nicht als Requisiten erkannt werden, „zurückgegriffen“ und als normale HTML-Attribute auf das Stammelement von auf das untergeordnete Element angewendet die Komponente. Beim Schreiben einer Komponente, die ein Zielelement oder eine andere Komponente umschließt, entspricht dies möglicherweise nicht immer dem erwarteten Verhalten. Durch Festlegen von inheritAttrs auf „false“ werden diese Standardverhalten entfernt. Diese Attribute können durch die Instanzeigenschaft $attrs wirksam gemacht und über v-bind explizit an Nicht-Root-Elemente gebunden werden.
Wir können also den folgenden Code schreiben, um die Requisiten und Ereignisse von Komponenten von Drittanbietern zu verarbeiten:
// MyInput.vue <template> <div class="my-input"> <el-input v-bind="attrs"></el-input> </div> </template> <script> export default { name: 'MyInput', inheritAttrs: false } </script> <script setup> import { useAttrs } from 'vue' const attrs = useAttrs() </script>
In Vue3
$slots: Wir können ihn verwenden Holen Sie sich den von der übergeordneten Komponente übergebenen Slot
$scopedSlots wurde in Vue3 entfernt und alle Slots werden als Funktionen über $slots verfügbar gemacht
Die Hilfsfunktion useSlots in 5101c0cdbdc49998c642c71f6b6410a8 kann $slots abrufen.
Wenn wir auf der Grundlage der oben genannten Punkte keine zusätzlichen Steckplätze für die Verpackung von Komponenten von Drittanbietern hinzufügen und sich die Steckplätze der Komponenten von Drittanbietern im selben Dom-Knoten befinden, haben wir dann auch eine knifflige Verpackungsmethode? ?? ?, erhalten Sie den Namen des Slots, indem Sie $slots durchlaufen, und fügen Sie dynamisch den Slot der Unterkomponente hinzu:
//MyInput.vue <template> <div class="my-input"> <el-input v-bind="attrs"> <template v-for="k in Object.keys(slots)" #[k] :key="k"> <slot :name="k"></slot> </template> </el-input> </div> </template> <script> export default { name: 'MyInput', inheritAttrs: false } </script> <script setup> import { useAttrs, useSlots } from 'vue' const attrs = useAttrs() const slots = useSlots() </script>
Wenn die oben genannten Bedingungen nicht erfüllt sind, müssen wir die Slots des erforderlichen Drittanbieters manuell hinzufügen Komponenten in der Unterkomponente ~
Für Methoden von Komponenten von Drittanbietern implementieren wir diese über ref. Fügen Sie zunächst ein ref="elInputRef"-Attribut zur el-input-Komponente in der MyInput-Komponente hinzu und machen Sie dann elInputRef über defineExpose für die übergeordnete Komponente verfügbar.
Unterkomponente: MyInput.vue
// MyInput.vue <template> <div class="my-input"> <el-input v-bind="attrs" ref="elInputRef"> <template v-for="k in Object.keys(slots)" #[k] :key="k"> <slot :name="k"></slot> </template> </el-input> </div> </template> <script> export default { name: 'MyInput', inheritAttrs: false } </script> <script setup> import { useAttrs, useSlots } from 'vue' const attrs = useAttrs() const slots = useSlots() const elInputRef = ref(null) defineExpose({ elInputRef // <script setup>的组件里的属性默认是关闭的,需通过defineExpose暴露出去才能被调用 }) </script>
Übergeordnete Seite: Der Aufrufcode von Index.vue lautet wie folgt:
// Index.vue <template> <my-input v-model='input' ref="myInput"> <template #prefix>姓名</template> </my-input> </template> <script setup> import MyInput from './components/MyInput.vue' import { ref, onMounted } from 'vue' const input = ref('') const myInput = ref(null) // 组件实例 onMounted(()=> { myInput.value.elInputRef.focus() // 初始化时调用elInputRef实例的focus方法 }) </script>
Das obige ist der detaillierte Inhalt vonWie die Vue3 Composition API Komponenten von Drittanbietern elegant kapselt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!