javascript - Vuex store 在不同模块中导入时创建一个新实例
问题描述
几天来,我一直在努力将我的 Vuex 商店导入多个不同的模块。出于某种原因,我的商店似乎正在为每次导入创建新实例。在一个 Vue 对象中,我正在为 store 设置一个值,但由于未知原因,我无法在另一个 Vue 对象中访问它。我有 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
在文档中,它被组织在一个文件中,我展示它的方式对应于“主模块”的一个文件,这实际上是你的商店,然后是一个模块一个文件。
推荐阅读
- python - 在 python 中使用 selenium Web 驱动程序检索变量文本的文本
- c# - 在另一个模型列表中的模型列表中求和和分组
- javascript - 当 nextTick 不起作用时,如何让 Vue 从 .vue 文件中立即更新实际的 DOM?
- wpf - WPF - XAML - DataGridRow 样式触发器 IsMouseOver 工具提示数据绑定
- c - 将条件语句定义为变量
- c# - 嵌套异步导致 HttpContext Null
- python - 从 URL 内容中拆分文本
- java - Android GPS 定位未发现问题。如何更正此代码
- powershell - 连接 Select-Object 语句中的两个属性
- python - ansible 动态库存错误