Rumah > hujung hadapan web > View.js > Cara API Komposisi Vue3 merangkum komponen pihak ketiga dengan elegan

Cara API Komposisi Vue3 merangkum komponen pihak ketiga dengan elegan

WBOY
Lepaskan: 2023-05-11 19:13:09
ke hadapan
1597 orang telah melayarinya

Kata Pengantar

Untuk komponen pihak ketiga, bagaimana untuk memanjangkan fungsi secara elegan sambil mengekalkan fungsi asal komponen pihak ketiga (prop, acara, slot, kaedah)?

Ambil el-input Element Plus sebagai contoh:

Kemungkinan besar anda pernah bermain seperti ini sebelum ini, merangkum komponen MyInput dan meletakkan prop, acara dan slot yang akan digunakan , tulis kaedah sekali lagi mengikut keperluan anda sendiri:

// 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 &#39;vue&#39;
const props = defineProps({
  modelValue: {
    type: String,
    default: &#39;&#39;
  },
  clearable: {
    type: Boolean,
    default: false
  }
})
const emits = defineEmits([&#39;update:modelValue&#39;, &#39;clear&#39;])
const inputVal = computed({
  get: () => props.modelValue,
  set: (val) => {
    emits(&#39;update:modelValue&#39;, val)
  }
})
const clear = () => {
  emits(&#39;clear&#39;)
}
</script>
Salin selepas log masuk

Tetapi selepas tempoh masa, keperluan berubah, dan fungsi lain komponen el-input perlu ditambahkan pada komponen MyInput Komponen el-input mempunyai sejumlah 20 Terdapat berbilang atribut, 5 acara, dan 4 slot Apa yang perlu kita lakukan satu persatu. Ini bukan sahaja menyusahkan tetapi juga mempunyai kebolehbacaan yang lemah.

Dalam Vue2, kami boleh mengendalikannya seperti ini, klik di sini untuk melihat enkapsulasi komponen pihak ketiga Vue

Artikel ini adalah untuk membantu anda memindahkan pengetahuan anda dan meneroka cara menggunakan Vue3 CompositionAPI untuk merangkum komponen pihak ketiga dengan elegan~

1 Untuk prop atribut dan acara komponen pihak ketiga

dalam Vue2

  • $attrs: termasuk pengikatan Atribut fungsi induk dalam domain yang tidak diiktiraf (dan diperoleh) sebagai prop (kecuali kelas dan gaya). Apabila komponen tidak mengisytiharkan sebarang prop, semua pengikatan skop induk (kecuali kelas dan gaya) akan disertakan di sini dan komponen dalaman boleh dihantar melalui v-bind="$attrs"

  • $pendengar: Mengandungi pendengar acara v-on dalam skop induk (tidak termasuk .pengubah suai asli). Ia boleh lulus v-on="$listeners" untuk lulus dalam komponen dalaman

dan dalam Vue3

  • $attrs: mengandungi induk peranan Pengikatan dan peristiwa atribut (termasuk acara kelas, gaya dan tersuai) yang tidak digunakan sebagai prop komponen atau peristiwa tersuai dalam domain juga boleh dihantar ke komponen dalaman melalui v-bind="$attrs".

  • Objek $listeners telah dialih keluar dalam Vue 3. Pendengar acara kini menjadi sebahagian daripada $attrs.

  • Fungsi tambahan useAttrs dalam

//MyInput.vue 
<template>
  <div class="my-input">
    <el-input v-bind="attrs"></el-input>
  </div>
</template>
<script setup>
import { useAttrs } from &#39;vue&#39;
const attrs = useAttrs()
</script>
Salin selepas log masuk

Sudah tentu, ini tidak mencukupi. Hanya menulis dengan cara ini, atribut yang kami ikat (termasuk kelas dan gaya) juga akan berkuat kuasa pada elemen akar (contoh di atas ialah nod Dom dengan class="my-input"). Untuk mengelakkan tingkah laku lalai ini, kita perlu menetapkan inheritAttrs kepada false.

Mari kita lihat penjelasan dokumen Vue3 tentang inheritAttrs

Secara lalai, pengikatan atribut dalam skop induk yang tidak dikenali sebagai prop akan "berbalik" dan Digunakan pada elemen akar komponen anak sebagai atribut HTML biasa. Apabila menulis komponen yang membungkus elemen sasaran atau komponen lain, ini mungkin tidak sentiasa mematuhi tingkah laku yang dijangkakan. Dengan menetapkan inheritAttrs kepada false, gelagat lalai ini akan dialih keluar. Atribut-atribut ini boleh dijadikan berkesan melalui instance property $attrs, dan boleh diikat secara eksplisit kepada elemen bukan akar melalui v-bind.

Jadi, kita boleh menulis kod berikut untuk memproses prop dan acara komponen pihak ketiga:

// MyInput.vue 
<template>
  <div class="my-input">
    <el-input v-bind="attrs"></el-input>
  </div>
</template>
<script>
export default {
  name: &#39;MyInput&#39;,
  inheritAttrs: false
}
</script>
<script setup>
import { useAttrs } from &#39;vue&#39;
const attrs = useAttrs()
</script>
Salin selepas log masuk

2. Untuk slot komponen pihak ketiga

Vue3

  • $slots: Kita boleh mendapatkan slot yang diluluskan oleh komponen induk

  • $scopedSlots telah dialih keluar daripada Vue3, semua Slot terdedah sebagai fungsi melalui $slots

  • Dalam , fungsi tambahan useSlots boleh mendapatkan $slot.

Berdasarkan perkara di atas, jika kami tidak menambah slot tambahan untuk pembungkusan komponen pihak ketiga, dan slot komponen pihak ketiga berada dalam nod dom yang sama, kami juga mempunyai kaedah pengkapsulan pintar A ????, dapatkan nama slot dengan merentasi $slot, dan tambah secara dinamik slot subkomponen:

//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: &#39;MyInput&#39;,
  inheritAttrs: false
}
</script>
<script setup>
import { useAttrs, useSlots } from &#39;vue&#39;
const attrs = useAttrs()
const slots = useSlots()
</script>
Salin selepas log masuk

Jika syarat di atas tidak dipenuhi, kami harus jujur ​​Tambah slot komponen pihak ketiga yang diperlukan dalam komponen secara manual~

3 Kaedah untuk komponen pihak ketiga

Untuk kaedah komponen pihak ketiga, kami melaksanakannya melalui ref. . Mula-mula, tambahkan atribut ref="elInputRef" pada komponen el-input dalam komponen MyInput, dan kemudian dedahkan elInputRef kepada komponen induk melalui defineExpose.

Komponen kanak-kanak: 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: &#39;MyInput&#39;,
  inheritAttrs: false
}
</script>
<script setup>
import { useAttrs, useSlots } from &#39;vue&#39;
const attrs = useAttrs()
const slots = useSlots()
const elInputRef = ref(null)
defineExpose({
  elInputRef  // <script setup>的组件里的属性默认是关闭的,需通过defineExpose暴露出去才能被调用
})
</script>
Salin selepas log masuk

Halaman induk: Kod panggilan Index.vue adalah seperti berikut:

// Index.vue 
<template>
  <my-input v-model=&#39;input&#39; ref="myInput">
    <template #prefix>姓名</template>
  </my-input>
</template>
<script setup>
import MyInput from &#39;./components/MyInput.vue&#39;
import { ref, onMounted } from &#39;vue&#39;
const input = ref(&#39;&#39;)
const myInput = ref(null) // 组件实例
onMounted(()=> {
  myInput.value.elInputRef.focus() // 初始化时调用elInputRef实例的focus方法
})
</script>
Salin selepas log masuk

Atas ialah kandungan terperinci Cara API Komposisi Vue3 merangkum komponen pihak ketiga dengan elegan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan