簡體   English   中英

Vuex store 在不同模塊中導入時創建一個新實例

[英]Vuex store creates a new instance when imported in different modules

幾天來,我一直在努力將我的 Vuex 商店導入多個不同的模塊。 出於某種原因,我的商店似乎正在為每次導入創建新實例。 在一個 Vue object 中,我正在為商店設置一個值,但由於我未知的原因,它在另一個 Vue object 中無法訪問。 我有 3 個文件:store.js、addresses.js 和 relation.js。 在 store.js 文件中存在以下代碼:

const Vue = require('vue').default;
const Vuex = require("vuex");

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        addresses: {
            address: 'test'
        }
    },
    mutations: {
        setAddress(state, payload) {
            state.addresses.address = payload;
        }
    },
    actions: {
        setAddress(state, payload) {
            state.commit('setAddress', payload);
        }
    },
    getters: {
        getAddress(state) {
            return state.addresses.address;
        }
    },
});

export default store;

我的addresses.js 包含:

import agent from '../agent.js';
const Vue = require("vue").default;
import __ from '../translations/translate';
import Swal from '../../../app-assets/vendors/js/extensions/sweetalert2.all.min'
import store from "../store";


var address = new Vue({
    el: '#address-form',
    data: {
        address: {
            id: null,
            postal_code: '',
            house_number: '',
            house_number_addition: '',
            street_name: '',
            place: '',
            country: defaultAddressCountry[0],
            latitude: null,
            longitude: null,
            extra_address_line: null,
            safety_instructions: null,
            notes: null,
            po_box_number: '',
            is_po_box: false
        },
        address_countries: addressCountries,
        inputErrors: {
            postal_code: '',
            house_number: '',
            street_name: '',
            place: '',
            po_box_number: '',
        }
    },
    methods: {
        completeAddress: function(){
            let self = this;
            if(this.address.postal_code && this.address.house_number && this.address.postal_code.length > 3 && this.address.house_number.length > 0){
                $('#complete-address i').addClass('rotate');
                agent.Address.completeAddress(this.address.postal_code, this.address.house_number.toString() + this.address.house_number_addition, this.address.country)
                    .then(function(response){
                        self.address.street_name = response.data.address.street;
                        self.address.place = response.data.address.locality;
                        self.address.latitude = response.data.location.latitude;
                        self.address.longitude = response.data.location.longitude;
                        $('#complete-address i').removeClass('rotate');
                        self.validateFields();
                    }).catch(function(){
                        $('#complete-address').addClass('text-color-red');
                        setTimeout(function(){
                            $('#complete-address').removeClass('text-color-red');
                        }, 1000)
                        $('#complete-address i').removeClass('rotate');
                        self.address.street_name = null;
                        self.address.place = null;
                        self.address.latitude = null;
                        self.address.longitude = null;
                });
            }else{
                if(!this.address.postal_code || this.address.postal_code.length <= 4){
                    $('#input-postal-code').addClass('has-error');
                }
                if(!this.address.house_number || this.address.house_number.length == 0){
                    $('#input-house-number').addClass('has-error');
                }
                setTimeout(function(){
                    $('#input-postal-code, #input-house-number').removeClass('has-error');
                }, 500)
            }
        },
        gotoMaps: function () {
            open('https://maps.google.com/?q=' + this.address.latitude + ', ' + this.address.longitude);
        },
        sanitizeFields: function(){
            this.address.postal_code = this.address.postal_code.replace(/[^0-9a-z]/gi, '').toUpperCase().substr(0, 6);
            this.address.house_number = this.address.house_number.replace(/[^0-9]+/g, '').substr(0, 4);
            this.address.house_number_addition = this.address.house_number_addition.replace(/[^0-9a-z]/gi, '').toUpperCase().substr(0, 2);
        },
        validateFields: function(){
            let has_errors = false;
            this.inputErrors.postal_code = '';
            if(this.address.postal_code.length < 5){
                this.inputErrors.postal_code = __('invalid input');
                has_errors = true;
            }
            if(this.address.postal_code.length === 0){
                this.inputErrors.postal_code = __('required');
                has_errors = true;
            }
            this.inputErrors.house_number = '';
            if(this.address.house_number.length === 0 && !this.address.is_po_box){
                this.inputErrors.house_number = __('required');
                has_errors = true;
            }
            this.inputErrors.street_name = '';
            if(this.address.street_name.trim().length === 0 && !this.address.is_po_box){
                this.inputErrors.street_name = __('required');
                has_errors = true;
            }
            this.inputErrors.place = '';
            if(this.address.place.trim().length === 0){
                this.inputErrors.place = __('required');
                has_errors = true;
            }
            this.inputErrors.po_box_number = '';
            if(this.address.po_box_number.trim().length === 0 && this.address.is_po_box){
                this.inputErrors.po_box_number = __('required');
                has_errors = true;
            }
            return !has_errors;
        },
        saveAddress: function(){
            if(this.address.is_po_box){
                this.address.street_name = '';
                this.address.house_number = '';
                this.address.house_number_addition = '';
                this.address.safety_instructions = null;
                this.address.extra_address_line = null;
                this.address.notes = null;
            }else{
                this.address.po_box_number = '';
            }
            if(this.validateFields()){
                let self = this;
                if(this.address.id) {
                    agent.Address.update(this.address);
                }else{
                    agent.Address.create(this.address).then(function (result) {
                        if(result.status)
                        self.address = result.data;
                    }).catch(function(error){
                        if(error.response.status === 409){
                            let house_number = [error.response.data.house_number];
                            if(error.response.data.house_number_addition){
                                house_number.push(error.response.data.house_number_addition);
                            }
                            Swal.fire({
                                title: __('Existing address was found'),
                                icon: 'info',
                                html: '' +
                                    '<table style="text-align:left;" class="table table-bordered">' +
                                        '<tr>' +
                                            '<td>'+__('Address')+'</td>' +
                                            '<td>'+error.response.data.street_name+' ' + house_number.join('-') + '</td>' +
                                        '</tr>' +
                                        '<tr>' +
                                            '<td>'+__('Postal code')+'</td>' +
                                            '<td>'+error.response.data.postal_code+'</td>' +
                                        '</tr>' +
                                        '<tr>' +
                                            '<td>'+__('Place')+'</td>' +
                                            '<td>'+error.response.data.place+'</td>' +
                                        '</tr>' +
                                        '<tr>' +
                                            '<td>'+__('Country')+'</td>' +
                                            '<td>'+error.response.data.country+'</td>' +
                                        '</tr>' +
                                    '</table>',
                                customClass: 'swal-wide',
                                showCancelButton: true,
                                confirmButtonText: __('Use this address'),
                                cancelButtonText: __('No, create a new one'),
                            }).then(function(result){
                                if(result.value === true){
                                    store.dispatch('setAddress', self.address)
                                    console.log(store.state.addresses.address)
                                }
                            });
                        }
                    });
                }
            }
        }
    },
    watch: {
        address: {
            handler(){
                if(this.address.is_po_box){
                    $('.no-po-box').hide();
                    $('#extra-address-info').hide();
                    $('#show-address-extra').attr('data-expanded', 'false');
                    $('#show-address-extra').find('i').removeClass('icon-chevron-up').addClass('icon-chevron-down');
                    $('.is-po-box').show();
                }else{
                    $('.no-po-box').show();
                    $('.is-po-box').hide();
                }
                this.sanitizeFields();
            },
            deep: true
        }
    },
    computed: {
        showMapsIcon: function(){
            return this.address.latitude && this.address.longitude;
        }
    },
    created(){
        $(document).on('click', '.address-selector', function(){
            $('#address-modal').modal();
        });
        $(document).on('click', '#show-address-extra', function(){
            if($(this).attr('data-expanded') == 'false') {
                $('#extra-address-info').slideDown();
                $(this).attr('data-expanded', 'true');
                $(this).find('i').removeClass('icon-chevron-down').addClass('icon-chevron-up');
            }else{
                $('#extra-address-info').slideUp();
                $(this).attr('data-expanded', 'false');
                $(this).find('i').removeClass('icon-chevron-up').addClass('icon-chevron-down');
            }
        });
        $('.dataTable').DataTable();
    },
    delimiters: ['[[' , ']]']
});

export default address;

我的 relation.js 文件:

import agent from '../../agent.js'
const Vue = require("vue").default;
import store from "../../store";


var relation = new Vue({
    el: '#upsert-relation-form',
    data: {
        relation: {
            id: null,
            name: null,
            is_supplier: false,
            is_customer: true,
            is_prospect: false,
            is_debtor: true,
            general_email_address: null,
            general_phone_number: defaultCountryCode,
            communication_language: languages.find(x => x.code == defaultLanguage[0])['code'],
            account_manager: null,
            tags: [],
            industries: [],
        },
        languages: languages,
        account_managers: [
            {
                id: 1,
                name: 'Piet de Vries'
            },
            {
                id: 2,
                name: 'Willem Aardappel'
            }
        ]
    },
    computed: {
        visiting_address(){
            console.log(store.getters.getAddress);
            return store.getters.getAddress;
        }
    },
    methods: {
        completeAddress: function(address){
            console.log(address);
        }
    },
    created(){
        let self = this;
        $(document).on('click', '.tags-container', function(){
            $(this).find('input').focus();
        });
        $(document).on('click', '.tags-container li a.remove', function(){
            let field = $(this).closest('.tags-container').attr('data-field');
            let val = $(this).closest('li').text().trim();
            let index = self.relation[field].findIndex(function(tag){
                return tag.value == val;
            });
            self.relation[field].splice(index, 1);
        });
        $(document).on('keyup', '.tags-container input', function(e){
            let field = $(this).closest('.tags-container').attr('data-field');
            if(e.keyCode === 13){
                let tagValue = $(this).val().trim().toLowerCase().replace(/[^a-zA-Z 0-9]+/g, '');
                if(tagValue.length < 3){
                    return;
                }
                let index = self.relation[field].findIndex(function(tag){
                    return tag.value == tagValue;
                });
                if(index !== -1){
                    $(this).val('');
                    return;
                }
                self.relation[field].push({
                    id: null,
                    value: tagValue
                });
                $(this).val('');
            }
        });
        $(document).on('keydown', '.tags-container input', function(e){
            let field = $(this).closest('.tags-container').attr('data-field');
            if(e.keyCode === 8 && $(this).val().trim().length === 0){
                self.relation[field].pop();
            }
        });
    },
    delimiters: ['[[' , ']]']
});

export default relation;

在addresses.js 中,我看到該值已正確設置為商店。 但是在relation.js 文件中,它仍然會在存儲啟動時獲取原始數據集。

它應該以相反的方式完成,您將模塊導入您的 vuex 而不是模塊中的 vuex。

所以你應該有一個看起來像這樣的“主模塊”:

  import Vue from 'vue';
  ///////////Vuex et store
  import Vuex from 'vuex';
  /////////////////Modules
  import media from "./modules/media";

  Vue.use(Vuex);

  export default new Vuex.Store({
    state: {
    },
    getters: {
    },
    mutations: {
    }
    ,
    actions: {
    },
    modules: {
      media
    }
  })

然后你的模塊應該是這樣的:

  const state = {
  };

  const getters = {
  };

  const mutations = {
  };

  const actions = {
  };

  export default {
      namespaced: true,
      state,
      getters,
      actions,
      mutations
};

命名空間部分是可選的,這里是文檔的鏈接: https://vuex.vuejs.org/fr/guide/modules.html

在文檔中,它被組織在一個文件中,我展示它的方式對應於“主模塊”的一個文件,這實際上是你的商店,然后是一個模塊一個文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM