Flazzo memiliki fokus utama untuk menambah nilai bisnis Anda.

Blog

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

jxCrLoZOCP9iYcb49vz1B4DADPl99UlcIyNo5msM.webp.webp
Blog

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:

  1. palmar/view-tsc@^1.6.4
  2. cepat@^4.3.5
  3. @vitejs/plugin-vue@^4.2.0
  4. 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, extendstipe 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 propsyang 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.