Memperkenalkan Vue 3.3: Apa yang Baru dan Apa yang Baru di TypeScript

Memperkenalkan Vue 3.3: Apa yang Baru dan Apa yang Baru di TypeScript
Tim Vue mengumumkan rilis versi 3.3 – “Rurouni Kenshin.”
Dalam versi baru ini, pengembang berfokus pada peningkatan pengalaman pengembangan. Misalnya, mereka meningkatkan interaksi dengan SFC <script setup>
di TypeScript.
Banyak masalah lama dengan penggunaan Vue dan TypeScript juga telah diselesaikan.
Perubahan utama
Pembaruan ketergantungan
Untuk memutakhirkan ke Vue 3.3, dependensi berikut juga harus diperbarui:
- palmar/view-tsc@^1.6.4
- cepat@^4.3.5
- @vitejs/plugin-vue@^4.2.0
- view-loader@^17.1.0 (jika Anda menggunakan webpack atau vue-cli)
Dukungan untuk tipe yang diimpor dan kompleks dalam makro
Sebelum versi 3.3, masukkan defineProps
Dan defineEmits
hanya bisa berupa tipe lokal dan hanya tipe literal yang didukung.
Hak Cipta TechPlanet.today
Ini karena Vue perlu mengurai properti prop untuk menghasilkan opsi saat runtime.
Sekarang, di versi 3.3, kompiler memungkinkan penggunaan tipe yang diimpor dan kompleks.
<script setup lang="ts">
import type { Props } from './foo'
// imported + intersection type
defineProps<Props undefined { extraProp?: string }>()
</script>
Perlu diketahui bahwa dukungan untuk tipe kompleks didasarkan pada AST, sehingga tidak semua tipe dapat didukung sepenuhnya. Misalnya, tipe kondisional tidak didukung sama sekali.
Anda dapat menggunakan tipe kondisional untuk satu parameter, tetapi tidak untuk objek parameter.
Komponen universal
Komponen dengan <script setup>
sekarang menerima parameter universal melalui generic
atribut:
<script setup lang="ts" generic="T">
defineProps<{
items: T[]
selected: T
}>()
</script>
ITU generic
atribut berfungsi sebagai daftar parameter antara <...>
di TypeScript.
Anda sekarang dapat menggunakan beberapa parameter, extends
tipe default dan tipe yang diimpor.
<script setup lang="ts" generic="T extends string | number, U extends Item">
import type { Item } from './types'
defineProps<{
id: T
list: U[]
}>()
</script>
Sebelumnya, fitur ini harus diaktifkan secara manual. Namun, dalam volar/vue-tsc versi terbaru disertakan secara default.
Sintaks defineEmits yang ditingkatkan
Sebelumnya, parameter untuk defineEmits
hanya mendukung sintaks penandatanganan panggilan:
// BEFORE
const emit = defineEmits<{
(e: 'foo', id: number): void
(e: 'bar', name: string, ...rest: any[]): void
}>()
Jenis cocok dengan jenis pengembalian untuk emit
, tetapi pendek dan tidak nyaman untuk ditulis. Di versi 3.3, cara mendeklarasikan lebih ergonomis emit
diperkenalkan:
// AFTER
const emit = defineEmits<{
foo: [id: number]
bar: [name: string, ...rest: any[]]
}>()
Dalam tipe literal, kunci mewakili nama acara dan nilainya mewakili tipe array yang mendefinisikan argumen tambahan.
Sintaks tanda tangan lama masih didukung.
Slot diketik dengan defineSlots
Baru defineSlots
Makro dapat digunakan untuk mendeklarasikan slot yang diharapkan dan propertinya:
<script setup lang="ts">
defineSlots<{
default?: (props: { msg: string }) => any
item?: (props: { id: number }) => any
}>()
</script>
ITU defineSlots()
Fungsi hanya menerima parameter tipe, tetapi tidak menerima argumen runtime.
Parameter tipe harus berupa literal tipe di mana kunci properti adalah nama lokasi dan nilainya adalah fungsi lokasi.
Argumen pertama dari fungsi tersebut adalah props
yang tipenya akan digunakan untuk slot props di template.
Nilai dari defineSlots
adalah objek slot yang sama yang dikembalikan oleh useSlots
.
Batas saat ini:
- Validasi lokasi belum diterapkan di volar/vue-tsc.
- Jenis pengembalian fungsi slot bisa apa saja, tetapi di masa mendatang dapat digunakan untuk memeriksa isi slot.
- Ada juga pilihan lokasi untuk digunakan
defineComponent
. Kedua API digunakan secara eksklusif sebagai petunjuk tipe untuk IDE dan vue-tsc.
Fitur Eksperimental:
- Destructuring Responsive Props: Fitur ini memungkinkan props yang didestrukturisasi untuk mempertahankan daya tanggapnya dan menyediakan cara yang lebih nyaman untuk mendeklarasikan nilai.
<script setup>
import { watchEffect } from 'vue'
const { msg = 'hello' } = defineProps(['msg'])
watchEffect(() => {
// accessing `msg` in watchers and computed getters
// tracks it as a dependency, just like accessing `props.msg`
console.log(`msg is: ${msg}`)
})
</script>
<template>{{ msg }}</template>
Fitur ini bersifat eksperimental dan memerlukan persetujuan eksplisit.
setModel
Sebelumnya, agar komponen mendukung pengikatan dua arah dengan v-model, ia harus mendeklarasikan properti dan membuat a update:propName
acara untuk memperbarui properti.
<!-- BEFORE -->
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
console.log(props.modelValue)
function onInput(e) {
emit('update:modelValue', e.target.value)
}
</script>
<template>
<input :value="modelValue" @input="onInput" />
</template>
Versi 3.3 menyederhanakan proses ini dengan defineModel
makro. Makro secara otomatis mendeklarasikan properti dan mengembalikan referensi ke sana.
<!-- AFTER -->
<script setup>
const modelValue = defineModel()
console.log(modelValue.value)
</script>
<template>
<input v-model="modelValue" />
</template>
Fitur ini bersifat eksperimental dan memerlukan persetujuan eksplisit.
Fitur penting lainnya:
setOptions
Makro defineOptions yang baru memungkinkan Anda mendeklarasikan opsi komponen secara langsung <script setup>
. Ini menghilangkan kebutuhan untuk a <script>
memblokir.
<script setup>
defineOptions({ inheritAttrs: false })
</script>
Peningkatan dukungan untuk Getter dengan toRef dan toValue
toRef
telah ditingkatkan untuk mendukung normalisasi nilai, getter, dan refs
.
// equivalent to ref(1)
toRef(1)
// creates a readonly ref that calls the getter on .value access
toRef(() => props.foo)
// returns existing refs as-is
toRef(existingRef)
Panggilan toRef
bisa lebih efisien ketika pengambil hanya perlu mengakses properti. Dalam kasus seperti itu, perhitungan yang panjang dan rumit tidak diperlukan.
Metode utilitas baru toValue
melakukan sebaliknya, menormalkan segalanya menjadi nilai.
toValue(1) // --> 1
toValue(ref(1)) // --> 1
toValue(() => 1) // --> 1
toValue
dapat digunakan dalam komponen komposit sebagai gantinya unref
agar komponen menerima getter sebagai sumber data reaktif.
// before: allocating unnecessary intermediate refs
useFeature(computed(() => props.foo))
useFeature(toRef(props, 'foo'))
// after: more efficient and succinct
useFeature(() => props.foo)
Perbedaan antara toRef
Dan toValue
adalah sama antara ref dan unref
. Satu-satunya perbedaan adalah bagaimana fungsi pengambil ditangani.
Mengimpor kode sumber JSX
Saat ini, tipe Vue secara otomatis mendaftarkan pengetikan JSX global, yang mungkin bertentangan dengan pustaka lain yang perlu mendefinisikan tipe JSX, khususnya React.
Pada versi 3.3, Vue mendukung penentuan pengetikan JSX menggunakan TypeScript jsxImportSource
pengaturan.
Perbaikan infrastruktur layanan
Berikut perbaikan yang dilakukan pada versi 3.3:
- Waktu build sekarang 10x lebih cepat berkat pemisahan pemeriksaan tipe dari bangunan monolitik dan transisi dari rollup-plugin-typescript2 ke rollup-plugin-esbuild.
- Pengujian telah dipercepat dengan berpindah dari Jest ke Vitest.
- Pembuatan tipe telah dipercepat dengan berpindah dari @microsoft/api-extractor ke rollup-plugin-dts.
- Pengujian regresi komprehensif menggunakan ekosistem-ci membantu mengidentifikasi regresi dalam dependensi utama sebelum dirilis.
Pada artikel ini, kami telah membahas perubahan besar pada versi 3.3. Anda dapat menemukan daftar lengkapnya pembaruan di GitHub.
Jika Anda menemukan kesalahan dalam teks, kirimkan pesan ke penulis dengan menyorot kesalahan dan menekan Ctrl-Enter.