Vuex - Thuộc tính tính toán “tên” đã được gán cho nhưng nó không có người thiết lập


108

Tôi có một thành phần với một số xác thực biểu mẫu. Đây là một hình thức thanh toán nhiều bước. Đoạn mã dưới đây là dành cho bước đầu tiên. Tôi muốn xác thực rằng người dùng đã nhập một số văn bản, lưu trữ tên của họ ở trạng thái toàn cục và sau đó gửi sang bước tiếp theo. Tôi đang sử dụng vee-validate và 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>

Tôi có một cửa hàng để xử lý trạng thái đơn hàng và ghi lại tên. Cuối cùng, tôi muốn gửi tất cả thông tin từ biểu mẫu nhiều bước đến máy chủ.

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

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

    }
  },

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

Khi tôi chạy mã này, tôi gặp lỗi Computed property "name" was assigned to but it has no setter.

Làm cách nào để liên kết giá trị từ trường tên với trạng thái chung? Tôi muốn điều này được duy trì để ngay cả khi người dùng quay lại một bước (sau khi nhấp vào "Bước tiếp theo"), họ sẽ thấy tên họ đã nhập ở bước này


1
Ngoài câu trả lời của Roy J, có vẻ như việc sử dụng v-fortrên máy tính mà không có bộ định vị cũng sẽ đưa ra cảnh báo này.
jsiegal

Câu trả lời:


191

Nếu bạn đang sử dụng v-modelmột máy tính, nó cần một bộ định vị . Bất cứ điều gì bạn muốn nó làm với giá trị được cập nhật (có thể ghi nó vào $store, coi đó là thứ mà getter của bạn lấy nó từ đó) bạn sẽ làm trong setter.

Nếu việc viết lại nó cho cửa hàng xảy ra thông qua việc gửi biểu mẫu, bạn không muốn v-model, bạn chỉ muốn thiết lập :value.

Nếu bạn muốn có một trạng thái trung gian, nơi nó được lưu ở đâu đó nhưng không ghi đè lên nguồn trong $storecho đến khi gửi biểu mẫu, bạn sẽ cần tạo một mục dữ liệu như vậy.


37
:valuehết v-model. Cảm ơn bạn!
Connor Leech

4
Cảm ơn bạn ... đã sửa cả [vue cảnh báo] của tôi. Tôi có một ngăn điều hướng yêu cầu giá trị true / false (chỉ đọc) nhưng tôi đã đặt một mô hình v vào đó.
GA

26

Nó phải như thế này.

Trong thành phần của bạn

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

Trong cửa hàng của bạn

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

1
Xin lỗi vì đã khôi phục một câu trả lời cũ của bạn, nhưng tại sao lại sử dụng getter trong trường hợp này? Tại sao không trả lại this.nameFromStore từ mapState? Nó hoạt động tốt rõ ràng.
Jake

@Jake Đối với ví dụ cụ thể này, điều bạn đang nói là đúng. Nhưng khi bạn muốn thao tác dữ liệu đã lưu trong store thì bạn có thể thực hiện điều đó bên trong getter nhưng nếu bạn sử dụng this.nameFromStoretrực tiếp thì bạn không thể thao tác dữ liệu.
OhhhThatVarun

1
Cảm ơn vì đã làm rõ :)
Jake

@Jake Không sao!
OhhhThatVarun

3

Đối với tôi, nó đang thay đổi.

this.name = response.data;

Đối với những gì tính toán trả về như vậy;

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

0

Tôi chỉ muốn đề cập đến lý do tại sao cảnh báo này xuất hiện, bất cứ khi nào chúng tôi tạo giá trị được tính toán thì nó sẽ là getter theo mặc định, chúng tôi cần xác định rõ ràng các bộ cài đặt cho thuộc tính tính toán,

như đã đề cập trong tài liệu của VueJs, Computed Setter

thuộc tính tính toán của bạn sẽ giống như thế này

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

Cách thích hợp hơn là bạn sử dụng mapStateđể lấy tên từ cửa hàng và tùy chọn khác mà bạn xác định getter trong cửa hàng của mình và sử dụng mapGettersđể trích xuất tên từ cửa hàng,

Điều quan trọng cần biết: getters trong cửa hàng được sử dụng khi bạn muốn lấy dữ liệu được tính toán từ cửa hàng, sau đó tại thời điểm đó bạn xác định logic trong getters để bạn có được dữ liệu được tính toán

ví dụ về getter

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

getter này kiểm tra trạng thái của bạn cho người dùng đang hoạt động và trả về true nếu đã đăng nhập và false nếu không đăng nhập,

sau này trong toàn bộ ứng dụng, chúng tôi sử dụng mapGettersđể trích xuất thuộc isLoggedIntính này và thêm các kiểm tra theo đó

hy vọng ai đó tìm thấy sự giúp đỡ này đầy đủ :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.