Rumah > Artikel > hujung hadapan web > Cara menggunakan v-model dalam vue3
Ambil komponen tersuai CustomInput
sebagai contoh
<script setup> const txt = ref(''); </script> <template> <CustomInput v-model="txt" /> </template>
v-model
akan dikembangkan ke dalam bentuk berikut
<CustomInput :modelValue="txt" @update:modelValue="newValue => txt = newValue" />
af7e595dcdbda7820db674c9e899f5bc
Dua perkara perlu dilakukan di dalam komponen:
Ikat atribut d5fd7aea971a85678ba271703566ebfd
unsur asli dalaman value
pada prop modelValue
Apabila acara input
asli dicetuskan, acara tersuai update:modelValue
yang membawa nilai baharu dicetuskan
Berikut ialah yang sepadan kod:
<script setup> const props = defineProps({ 'modelValue': String, }) const emit = defineEmits(["update:modelValue"]) </script> <template> <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template>
Sesetengah orang mungkin berpendapat bahawa cara penulisan ini terlalu rumit dan akan menyebabkan kod tag menjadi panjang
Cara lain untuk melaksanakan v-model
dalam komponen ialah menggunakan boleh ditulis, dengan Apabila menggunakan atribut computed
getter dan setter
, kaedah computed
perlu mengembalikan get
prop, dan kaedah modelValue
perlu mencetuskan Peristiwa yang sepadan set
<script setup> const value = computed({ get() { return props.modelValue }, set(value) { emit("update:modelValue", value) } }) </script> <template> <input v-model="value" /> </template>Cara penulisan ini boleh memudahkan atribut dalam teg, dan logiknya jelasSatu atribut boleh dikendalikan dengan mudah menggunakan
Bagaimana jika berbilang atribut memerlukan pengikatan dua hala?v-model
menggunakan v-model
sebagai prop pada komponen dan menggunakan modelValue
sebagai acara yang sepadan update:modelValue
: v-model
<template> <CustomInput v-model:first-name="first" v-model:last-name="last" /> </template>Begitu juga, ia juga boleh diikat dalam dua cara, tetapi
berubah daripada prop
asal kepada diluluskan dalam Nama parameter, peristiwa yang sepadan juga telah menjadi modelValue
update:参数名
<script setup> const props = defineProps({ firstName: String, lastName: String, }) // 在computed中 使用 const emit = defineEmits(['update:firstName', 'update:lastName']) </script> <template> <input type="text" :value="firstName" @input="$emit('update:firstName', $event.target.value)" /> <input type="text" :value="lastName" @input="$emit('update:lastName', $event.target.value)" /> </template>Objek pengikatDalam komponen yang kompleks, jika berbilang medan memerlukan pengikatan dua hala, jika anda menggunakan di atas kaedah yang ditunjukkan agak menyusahkan Memperkenalkan dua kaedah objek pengikat dua halaTentukan komponen induk
sebagai komponen bentuk komplekssearchBar
<script setup> import { ref } from "vue" const modelValue = ref({ keyword: "123", selectValue: "", options: [ { label: "全部", value: "" }, { label: "a1", value: "1" }, { label: "a2", value: "2" }, ] }) </script> <template> <searchBar v-model="modelValue" /> </template>Kemudian Dalam
komponen, kami menerima searchBar
dan mentakrifkan jenis sebagai modelValue
Object
<template> <div> <!-- <input type="text" v-model="modelValue.keyword"> 可以实现双向绑定 --> <input type="text" :value="modelValue.keyword" @input="handleKeywordChange" > <select v-model="modelValue.selectValue"> <option v-for="o in modelValue.options" :key="o.value" :value="o.value"> {{ o.label }} </option> </select> </div> </template> <script lang="ts" setup> const props = defineProps({ modelValue: { type: Object, default: () => ({}) } }) const emit = defineEmits(["update:modelValue"]); // 以 input 举例 const handleKeywordChange=(val)=>{ emit("update:modelValue",{ ...props.modelValue, keyword:val.target.value }) } </script>
Jika objek dimasukkan, seperti yang diterangkan dalam ulasanadalah sama dengan peristiwa pencetus
walaupun ia boleh dilakukan secara langsung pengikatan dua hala, tetapi ini akan memusnahkan5639db6519b7c785e0bd88ac866814a1
aliran data tunggal
di atas, tetapi data yang diluluskan menjadi objekemit
computed + prxoy
mengikat, anda boleh menulis kod ini computed
<template> <input type="text" v-model="model.keyword"> </template> <script lang="ts" setup> const model = computed({ get() { return props.modelValue }, set(value) { // console.log(value) // 发现没有打印 emit("update:modelValue", { ...props.modelValue, keyword: value }) } }) <script>tetapi apabila anda masuk, anda akan mendapati bahawa
tidak dicetuskan, kerana setter
akan melakukan lapisan proksi, Objek proksi belum diubah suai computed
, seperti yang ditunjukkan di bawah: setter
// 只有这样才会变化 model.value = { keyword:"asdfad" }Kaedah ini tidak boleh mencetuskan
, dan oleh itu pengikatan dua hala tidak boleh dilakukan Apa yang perlu saya lakukan? setter
objek proksi dalam getter
! mengembalikan objek proksi dalam getter
! mengembalikan objek proksi dalam getter
!
konsisten dengan objek proksi, kami menggunakan proxy
untuk membalut objek asal proxy
ialah terikat kepada Untuk objek selepas proksi, jika sifat objek proksi berubah, kaedah v-model
dalam objek proksi akan dicetuskan Pada masa ini, kita boleh mencetuskan pengubah suai set
emit
const model = computed({ get() { return new Proxy(props.modelValue, { set(obj, name, val) { emit("update:modelValue", { ...obj, [name]: val }) return true } }) }, set(value) { emit("update:modelValue", { ...props.modelValue, keyword: value }) } }). seperti yang kita tahu
mempunyai beberapa pengubah suai terbina dalam, seperti v-model
, .trim
dan .number
. .lazy
menyokong pengubah suai tersuai. v-model
, yang secara automatik akan menukar huruf pertama nilai rentetan yang terikat kepada capitalize
kepada huruf besar: v-model
<CustomInput v-model.capitalize="txt" />Kami menambah Dengan pengubah
, ia akan dihantar secara automatik ke dalam capitalize
<script setup> const props = defineProps({ modelValue: String, modelModifiers: { default: () => ({}) } }) const emitValue = (e) => { let value = e.target.value; // 使用 修饰符 if (props.modelModifiers.capitalize) { value = value.charAt(0).toUpperCase() + value.slice(1) } emit('update:modelValue', value) } </script> <template> <input :value="modelValue" @input="emitValue" /> </template>dalam
prop
modelModifiers
dalam Atas ialah kandungan terperinci Cara menggunakan v-model dalam vue3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!