Vuex - Properti "nama" yang dihitung telah ditetapkan tetapi tidak memiliki penyetel


108

Saya memiliki komponen dengan beberapa validasi formulir. Ini adalah formulir pembayaran multi langkah. Kode di bawah ini untuk langkah pertama. Saya ingin memvalidasi bahwa pengguna memasukkan beberapa teks, menyimpan nama mereka di status global dan kemudian mengirimkannya ke langkah berikutnya. Saya menggunakan vee-validate dan vuex

<template>
<div>
    <div class='field'>
        <label class='label' for='name'>Name</label>
        <div class="control has-icons-right">

            <input name="name" v-model="name" v-validate="'required|alpha'" :class="{'input': true, 'is-danger': errors.has('name') }" type="text" placeholder="First and Last">
            <span class="icon is-small is-right" v-if="errors.has('name')">
                <i class="fa fa-warning"></i>
            </span>
        </div>
        <p class="help is-danger" v-show="errors.has('name')">{{ errors.first('name') }}</p>

    </div>
    <div class="field pull-right">
        <button class="button is-medium is-primary" type="submit" @click.prevent="nextStep">Next Step</button>
    </div>
</div>
</template>

<script>
export default {
    methods: {
        nextStep(){
            var self = this;

            // from baianat/vee-validate
            this.$validator.validateAll().then((result) => {
                if (result) {
                    this.$store.dispatch('addContactInfoForOrder', self);
                    this.$store.dispatch('goToNextStep');
                    return;
                }
            });
        }
    },
    computed: {
        name: function(){
            return this.$store.state.name;
        }
    }
}
</script>

Saya memiliki toko untuk menangani status pesanan dan mencatat nama. Akhirnya saya ingin mengirim semua info dari formulir multi langkah ke server.

export default {
  state: {
    name: '',
  },

  mutations: {
    UPDATE_ORDER_CONTACT(state, payload){
      state.name = payload.name;

    }
  },

  actions: {
    addContactInfoForOrder({commit}, payload) {
      commit('UPDATE_ORDER_CONTACT', payload);
    }
  }
}

Ketika saya menjalankan kode ini saya mendapatkan kesalahan itu Computed property "name" was assigned to but it has no setter.

Bagaimana cara mengikat nilai dari bidang nama ke status global? Saya ingin ini gigih sehingga meskipun pengguna mundur satu langkah (setelah mengklik "Langkah Berikutnya") mereka akan melihat nama yang mereka masukkan pada langkah ini


1
Selain jawaban Roy J, sepertinya penggunaan v-forpada komputer tanpa setter juga memberikan peringatan ini.
jsiegal

Jawaban:


192

Jika Anda akan v-modelmenghitung, itu membutuhkan penyetel . Apa pun yang Anda ingin lakukan dengan nilai yang diperbarui (mungkin tuliskan ke $store, mengingat dari situlah pengambil Anda menariknya) Anda lakukan di penyetel.

Jika menulisnya kembali ke toko terjadi melalui pengiriman formulir, Anda tidak mau v-model, Anda hanya ingin mengatur :value.

Jika Anda ingin memiliki status perantara, yang disimpan di suatu tempat tetapi tidak menimpa sumber $storehingga pengiriman formulir, Anda harus membuat item data seperti itu.


38
:valueberakhir v-model. Terima kasih!
Connor Leech

4
Terima kasih ... perbaiki [vue warn] saya juga. Saya memiliki panel samping navigasi yang membutuhkan nilai benar / salah (hanya-baca) tetapi saya telah meletakkan model-v padanya.
GA

26

Seharusnya seperti ini.

Di Komponen Anda

computed: {
        ...mapGetters({
                nameFromStore: 'name'
            }),
        name: {
           get(){
             return this.nameFromStore
           },
           set(newName){
             return newName
           } 
        }
    }

Di toko Anda

export const store = new Vuex.Store({
         state:{
             name : "Stackoverflow"
         },
         getters: {
                 name: (state) => {
                     return state.name;
                 }
         }
}

1
Maaf telah menghidupkan kembali jawaban lama Anda, tetapi mengapa menggunakan getter dalam kasus ini? Mengapa tidak mengembalikan this.nameFromStore dari mapState? Ini bekerja dengan baik rupanya.
Jake

@Jake Untuk contoh yang diberikan ini apa yang Anda katakan itu benar. Tetapi ketika Anda ingin memanipulasi data yang disimpan di toko maka Anda dapat melakukannya di dalam pengambil tetapi jika Anda menggunakan this.nameFromStoresecara langsung maka Anda tidak dapat memanipulasi data.
OhhhThatVarun

1
Terima kasih atas klarifikasinya :)
Jake

@Jake Tidak masalah!
OhhhThatVarun

3

Bagi saya itu berubah.

this.name = response.data;

Untuk apa yang dihitung kembali begitu;

this.$store.state.name = response.data;

0

Saya hanya ingin menyebutkan mengapa peringatan ini muncul, setiap kali kita membuat nilai yang dihitung itu getter secara default, kita secara eksplisit perlu mendefinisikan setter untuk properti yang dihitung,

seperti yang disebutkan dalam dokumentasi VueJs, Computed Setter

properti terhitung Anda akan terlihat seperti ini

   name: {
       get: function () {
          return yourName
       },
       set: function (newName) {
          return yourNewName
       }

Cara yang lebih tepat adalah Anda menggunakan mapStateuntuk mendapatkan nama dari toko, dan opsi lain yang Anda tentukan pengambil di toko Anda dan gunakan mapGettersuntuk mengekstrak nama dari toko,

Hal penting untuk diketahui: getter di toko digunakan ketika Anda ingin mendapatkan data yang dihitung dari penyimpanan, lalu pada saat itu Anda mendefinisikan logika dalam getter yang membuat Anda mendapatkan data yang dihitung

contoh pengambil

getters = {
  isLoggedIn (state) {
    return !!state?.activeUser?.id
  }
}

pengambil ini memeriksa status Anda untuk pengguna aktif dan mengembalikan true jika login dan false jika tidak login,

kemudian di seluruh aplikasi kami gunakan mapGettersuntuk mengekstrak isLoggedInproperti ini dan menambahkan pemeriksaan sesuai dengan itu

berharap seseorang menemukan bantuan ini penuh :)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.