Cara Menggunakan V-Model Directive Di Vuejs - CRUDPRO

Cara Menggunakan V-Model Directive Di Vuejs

Cara Menggunakan V-Model Directive Di Vuejs

Jika Anda seorang pengembang Vue Js seperti saya, Anda akan atau pasti akan menemukan direktif “v-model” yang sangat menarik. Mari selami banyak detail tentangnya.

Arahan model-V adalah pendekatan yang sangat membantu dan sangat bersih untuk mengikat perubahan apa pun ke nilai dan juga mendengarkan perubahannya.

Implementasinya yang paling sederhana adalah sebagai berikut:

Kotak input yang nilainya disimpan dalam variabel inputValue dan mendengarkan perubahan menggunakan @input

<template>
    <input :value="inputValue" @input="inputValue =  
    $event.target.value"/>
</template>

dapat ditulis menggunakan v-model sebagai:

<template>
    <input v-model="inputValue"/>
</template>
"InputValue" kami adalah properti reaktif dan karenanya harus ada baik sebagai properti data atau properti yang dihitung.

Menggunakan sebagai properti data, kita dapat melihat perubahannya menggunakan Vue watcher

data() {
    return {
        inputValue: ""
    }
},

watch: {
    inputValue(newValue, oldValue) {
        console.log(newValue, oldValue)
    }
}

Baik inisialisasi dan menonton pembaruan juga dapat dicapai dengan menggunakan properti pengakses get() dan set() di kait yang dihitung. Properti pengakses tidak lain adalah fungsi yang dipanggil saat mendapatkan dan menetapkan nilai.

computed: {
    inputValue: {
        get() {
            return this.updatedInputValue;
        },

        set(newValue) {
            this.updatedInputValue = newValue;
        }
    }
}
Namun menggunakan properti set accessor, kita tidak akan bisa mendapatkan oldValue dibandingkan saat menggunakan watcher.

Kita telah melihat bagaimana v-model bekerja pada input sederhana, sekarang mari kita lihat penggunaannya yang lebih kompleks.

Tombol radio

Tombol radio menyediakan opsi untuk memilih satu di antara banyak, maka model-v akan menyimpan hanya satu nilai primitif yang merupakan nilai yang dipilih.

<template>
    <div>
        <input type="radio" v-model="selectedRadioValue" id="radio1"             
        value="Value1">
        <label for="radio1">Car</label>
    
        <input type="radio" v-model="selectedRadioValue" id="radio2" 
        value="Value2">
        <label for="radio2">Bike</label>
    </div>
</template>
dipilihRadioValue harus menjadi nilai reaktif dan tergantung pada pilihan akan menyimpan Nilai1 atau Nilai2.
Catatan: Sangat penting untuk memberikan atribut nilai untuk setiap elemen input di sini. Atribut ini adalah atribut yang ditetapkan ke properti selectedRadioValue kami. Jika kita tidak memberikan atribut value maka atribut tersebut ditetapkan sebagai null untuk setiap elemen input dan kemudian pada pilihan radio apa pun, semua tombol radio akan dipilih dengan nilai null

Kotak Centang

Kotak centang dapat berupa pilihan tunggal atau pilihan ganda dan model v akan menjadi

  • Nilai boolean untuk pilihan tunggal, yang menunjukkan apakah kotak centang dipilih atau tidak. Dalam contoh yang ditunjukkan di bawah ini, "dicentang" akan menjadi properti data yang menyimpan benar atau salah.
  • <input type=”checkbox” id=”checkbox1” v-model=”checked”>
    	<label for="checkbox1">Checked</label>
  • Array nilai yang menunjukkan nilai yang dipilih untuk multi-pilih. Di sini dicentang diinisialisasi ke array kosong ([]) dan diisi dengan nilai yang dipilih.
  • <input type=”checkbox” id=”checkbox1" v-model=”checked”  
        value=”Checked 1">
    	<label for=”checkbox1">Audi</label>
    	<input type=”checkbox” id=”checkbox2" v-model=”checked” 
    	    value=”Checked 2">
    	<label for=”checkbox2">Jaguar</label>
    	<input type=”checkbox” id=”checkbox3" v-model=”checked” 
    	    value=”Checked 3">
    	<label for=”checkbox3">Porsche</label>
Catatan: Penting untuk memberikan atribut value di sini juga, jika kita tidak memberikannya, null akan ditetapkan sebagai nilainya dan pada pilihan kotak centang apa pun, semua kotak centang akan dipilih dengan nilai sebagai null.

Pilih

Pilih lagi dapat menjadi pilihan tunggal atau multi-pilih dan dengan demikian model v-nya dapat

  • Nilai primitif dalam kasus pemilihan tunggal. Di sini yang dipilih akan menjadi nilai primitif dan tergantung pada pemilihan, Audi/Jaguar/Porsche akan ditugaskan ke "yang dipilih".
  • <select v-model=”selected”>
    	 <option selected>Audi</option>
    	 <option>Jaguar</option>
    	 <option>Porsche</option>
    	</select>
  • Array dalam kasus multi-pilih. Di sini yang dipilih adalah array dan pada pilihan apa pun, nilai yang dipilih akan didorong ke array yang dipilih.
  • <pilih v-model=”dipilih” beberapa>
    	  <opsi dipilih>Audi</option>
    	  <option>Jaguar</option>
    	  <option>Porsche</option>
    		</pilih>
Catatan: Seperti yang telah Anda perhatikan, atribut nilai dalam elemen opsi tidak wajib di sini dibandingkan dengan untuk Radio dan Kotak Centang. Jika atribut value tidak ada, nilai innerText elemen opsi akan ditetapkan ke properti "terpilih" kami. Tetapi jika ada, itu akan menimpa nilai teks-dalam dan ditugaskan ke "yang dipilih".
Radio, Kotak Centang, dan Pilih memancarkan peristiwa "perubahan" pada pemilihan yang ditangkap oleh model-v.

Antar Komponen

v-model juga dapat digunakan antara komponen parent dan child relationship. Ini digunakan sebagai singkatan untuk

  1. meneruskan prop sebagai "nilai" dari orang tua ke anak dan
  2. juga mendengarkan perubahan apa pun melalui acara input yang dipancarkan dari anak ke orang tua.

Misalnya, kami memiliki komponen induk: App.vue

<template>
    <div id="app">
        Enter user count : <input v-model.number="userCount" />
        
        <div v-for="(user, index) in userCount" :key="user">
            <user-details v-model="allUsersModel[index]" />
        </div>
        <div>allUsersModel: {{$data.allUserModel}}</div></div>
</template>

<script>
    import userDetails from "./components/userDetails";

    export default {
        name: "App",
        components: {
            userDetails,
        },        
        data() {
            return {
                userCount: 0,
                allUsersModel: [],
            };
        }
    };
</script>

Komponen turunan: UserDetails.vue

<template>
    <div>Name: <input v-model="nameModel" /></div>
</template>

<script>
    export default {
        name: "userDetails",
        props: {
            value: {
                required: true
            },
        },
        watch: {
            nameModel(newValue, oldValue) {
                console.log(newValue, oldValue);
                this.$emit("input", newValue);
            },
        },
        data() {
            return {
                nameModel: this.value
            };
        }
    };
</script>

Beberapa poin penting yang perlu diperhatikan di sini:

1. Kita tidak boleh mencoba mengubah prop secara langsung yaitu, kita tidak boleh menggunakan <input v-model="value" />di UserDetails.vue Vue akan memberikan peringatan:

Cara Menggunakan V-Model Directive Di Vuejs

[Peringatan Vue]: Hindari mengubah prop secara langsung karena nilainya akan ditimpa setiap kali komponen induk dirender ulang. Sebagai gantinya, gunakan data atau properti yang dihitung berdasarkan nilai prop. Prop sedang bermutasi: "nilai"

Menariknya, peringatan ini tidak dilontarkan saat kita menggunakan “:value” dan “@input”

<input :value="value" @input="$emit('input', $event.target.value)"/>

2. Di App.vue, kami telah menggunakan v-model.number, di sini nomor adalah pengubah, lebih pada itu menjelang akhir.

3. Pada setiap komponen detail pengguna individu, kami menggunakan v-model="allUsersModel[indeks]". allUsersModel adalah larik yang menyimpan dan mengikat nilai yang dipancarkan dengan kejadian input menggunakan this.$emit(“input”, newValue) dari UserDetails.vue

Struktur Sangat Bersarang

Sekarang jika kita ingin menampilkan beberapa bidang lagi di UserDetails seperti usia, kita dapat membuat struktur bersarang yang dalam untuknya, di allUsersModel dan menggunakannya sebagai v-model.

Komponen induk: App.vue

<template>
    <div id="app">
        Enter user count : <input v-model.number="userCount" />
        <div v-for="(user, index) in userCount" :key="user">
           <user-details v-model="allUsersModel[index].userModel" />
        </div>
        <div>allUsersModel: {{$data.allUsersModel}}</div></div>
</template>

<script>
    import userDetails from "./components/userDetails";

    export default {
        name: "App",
        data() {
            return {
                userCount: 0,
                allUsersModel: [],
            };
        },
        components: {
            userDetails,
        },
        watch: {
            userCount(newValue, oldValue) {
                if(newValue) {
                    this.allUsersModel = [];
                    for(var i = 0; i < newValue; i++ ) {
                        this.allUsersModel.push({
                            userModel: {
                                name: undefined,
                                age: undefined
                            }
                        })
                    }
                }
            },

            allUsersModel: {
                handler: function(newValue) {
                    console.log("allUsersModel: ",newValue);
                },
                deep: true
            },
        }
    };
</script>

Komponen turunan: UserDetails.vue

<template>
  <div>
    <span>
      Name: <input v-model="nameModel" />
    </span>
    <span>
      Age: <input v-model="ageModel" /> 
    </span>
  </div>
</template>

<script>
    export default {
        name: "userDetails",
        props: {
            value: {
                required: true,
            },
        },
        watch: {
            localModel(newValue, oldValue) {
                console.log(newValue, oldValue);
                this.$emit("input", newValue);
            },
        },
        data() {
            return {
                nameModel: this.value.name,
                ageModel: this.value.age
            };
        },
        computed: {
            localModel() {
                return {
                    name: this.nameModel,
                    age: this.ageModel
                }
            }
        }
    };
</script>

Poin penting yang perlu diperhatikan di sini adalah:

  1. Dalam komponen induk, kita menggunakan allUsersModel[index].userModel sebagai v-model. properti userModel pada setiap indeks akan menyimpan dan mengikat dan juga mendengarkan perubahannya melalui event input dari komponen anak.
  2. Karena allUsersModel sekarang menjadi array objek yang sangat bersarang, kita harus menggunakan "deep: true" di pengamatnya, jika tidak, pengamat tidak akan dipanggil.
  3. Di komponen turunan, kami telah membuat properti data nameModel dan ageModel, karena kami tidak dapat mengubah "value prop". Kami menggunakannya sebagai v-model untuk komponen anak.
  4. Kami juga telah membuat properti terkomputasi yang disebut “localModel”, yang diperbarui setiap kali nilai prop dari induk berubah atau nameModel atau ageModel dari anak berubah. Sekarang ini berguna untuk hanya mengawasi dan memancarkan ini dengan acara input.

Pendekatan ini sekarang dapat diperluas ke sejumlah level dalam hierarki komponen yaitu induk -> anak -> cucu -> ….. dengan menerima prop nilai pada anak dari orang tua dan memancarkan acara input ke orang tua.

Melihat objek/array bersarang dalam

Seperti yang kita ketahui saat memperbarui nilai dan referensi turunan dari sebuah array, referensi dari array luar akan tetap sama, kecuali jika kita melakukan JSON.parse(JSON.stringify(array)) yaitu. membuat salinan yang dalam.

Pada baris yang sama dengan pembaruan nama/usia apa pun, Vue akan memperbarui nilai dan referensi dari userModel (anak dari allUsersModel), tetapi referensi dari allUsersModel akan tetap sama.

Dalam hal ini, jika kita menonton di allUsersModel, kita tidak akan mendapatkan nilai lama, karena referensi Nilai baru dan Nilai lama akan sama dan Vue tidak melacak nilai lama.

Dalam kasus seperti itu, jika kita sangat membutuhkan OldValue, katakanlah untuk membandingkan oldValue dan newValue dan mengambil tindakan hanya jika keduanya tidak sama, v-model tidak akan membantu di sini. Di sini, kita harus menggunakan “:value” dan “/@input”

<user-details :value="allUsersModel[index].userModel" @input="val => onModelUpdate(val)" />

Menyesuaikan model-v pada komponen

Jika kita tidak ingin menggunakan prop nilai default dan event input pada v-model, kita dapat menyesuaikannya menggunakan opsi “model” di komponen turunan.

Dalam opsi model, kami menyediakan properti prop dan event baru yang akan digunakan untuk model-v dari induknya.

Misalnya, untuk pilih, kami dapat mengirim acara perubahan sebagai berikut:

Komponen induk: App.vue

<template>
    <vacation v-model="location" />
</template>

<script>
    import vacation from "./components/vacation";

    export default {
        name: "App",
        components: {
            vacation,
        },
        data() {
            return {
                location: undefined,
            };
        },
        watch: {
            location(newValue, oldValue) {
                console.log(newValue, oldValue);
            },
        },
    };
</script>

Komponen turunan: Vacation.vue

<template>
    <div>
        Select next vacation
        <select :value="value" @change="$emit('change',  
        $event.target.value)">
            <option>Hills</option>
            <option>Lakes</option>
            <option>Beaches</option>
        </select>
    </div>
</template>

<script>
    export default {
        name: "HelloWorld",
        model: {
            prop: "value",
            event: "change",
        },
        props: {
            value: String,
        },
    };
</script>

Pengubah

  1. .nomor Secara default, nilai input akan berupa string. Jika kita ingin input disimpan sebagai angka, alih-alih menggunakan parseInt di JS, kita bisa langsung menggunakan v-model.number yang akan mengembalikan nilai input dalam angka.
  2. .memangkas Ini sekali lagi merupakan pengubah yang berguna untuk memangkas nilai input dari spasi putih apa pun.
  3. .malas Secara default, dengan setiap kejadian input pada elemen input, sinkronisasi terjadi dengan nilainya. Kita dapat mengubahnya sedemikian rupa sehingga sinkronisasi terjadi dengan acara perubahan menggunakan pengubah .lazy.

KESIMPULAN

Kami telah membahas tentang direktif model-v dan berbagai cara untuk menggunakannya baik pada input sederhana/pilih hingga komponen yang lebih rumit. Kita dapat melihat bahwa mereka sangat mudah dipelajari dan digunakan dan juga membantu kita dalam menulis kode yang sangat bersih.

Saya harap artikel ini bermanfaat. Terimakasih