Rumah  >  Artikel  >  hujung hadapan web  >  Cara menggunakan v-model dalam vue3

Cara menggunakan v-model dalam vue3

王林
王林ke hadapan
2023-05-10 11:07:321803semak imbas

Ikat satu atribut

Ikatan asas

Ambil komponen tersuai CustomInput sebagai contoh

<script setup>
    const txt = ref(&#39;&#39;);
 </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({
  &#39;modelValue&#39;: String,
})
const emit = defineEmits(["update:modelValue"])
</script>

<template>
    <input :value="modelValue" @input="$emit(&#39;update:modelValue&#39;, $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

computed binding

, 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 jelas

Satu atribut boleh dikendalikan dengan mudah menggunakan

Bagaimana jika berbilang atribut memerlukan pengikatan dua hala?v-model

v-model mengikat berbilang atribut

Secara lalai,

menggunakan v-model sebagai prop pada komponen dan menggunakan modelValue sebagai acara yang sepadan update:modelValue

Tetapi kita boleh menukar nama ini dengan menyatakan parameter kepada

: 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 modelValueupdate:参数名

 <script setup>
 const props = defineProps({
  firstName: String,
  lastName: String,
})
// 在computed中 使用
const emit = defineEmits([&#39;update:firstName&#39;, &#39;update:lastName&#39;])
</script>

<template>
  <input
    type="text"
    :value="firstName"
    @input="$emit(&#39;update:firstName&#39;, $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"
    @input="$emit(&#39;update:lastName&#39;, $event.target.value)"
  />
</template>

Objek pengikat

Dalam 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 hala

Tentukan 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 modelValueObject

<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 ulasan


walaupun ia boleh dilakukan secara langsung pengikatan dua hala, tetapi ini akan memusnahkan 5639db6519b7c785e0bd88ac866814a1 aliran data tunggal

adalah sama dengan peristiwa pencetus

di atas, tetapi data yang diluluskan menjadi objekemit

Walaupun menggunakan emit boleh mencetuskan pengikatan dua hala, ianya terlalu menyusahkan cara penulisan yang lebih elegan, yang boleh dikatakan satu helah pelik -

computed + prxoy

Jika anda menggunakan

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

Jika anda ingin mencetuskan

, 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

mengembalikan

objek proksi dalam getter! mengembalikan objek proksi dalam getter! mengembalikan objek proksi dalam getter!

Oleh kerana sifat objek proksi

konsisten dengan objek proksi, kami menggunakan proxy untuk membalut objek asal proxy

maka

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 setemit

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

Dalam sesetengah senario, kami mungkin mahu komponen tersuai

menyokong pengubah suai tersuai. v-model

Mari buat pengubah suai tersuai

, 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(&#39;update:modelValue&#39;, value)
}
</script>

<template>
  <input :value="modelValue" @input="emitValue" />
</template>
dalam propmodelModifiers dalam

Atas ialah kandungan terperinci Cara menggunakan v-model dalam vue3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam