vue.js - 如何在渲染组件之前加载 Vuex 数据?
问题描述
我在 vuex 模块中调用天气 API。我想要完成的是使用组件中的计算属性获取数据。使用当前设置,除了我需要刷新/重新加载页面以更新 vuex 状态外,没有任何问题。我已经尝试调度在已安装的钩子中获取数据的操作,但这也不起作用,因此必须手动重新加载页面才能为计算的属性分配数据。这样做的正确方法是什么?
Vuex store.js
import Vue from 'vue';
import Vuex from 'vuex';
import {
Auth
} from 'aws-amplify';
import axios from 'axios';
var AWS = require('aws-sdk');
var AWSCognito = require('amazon-cognito-identity-js');
Auth.currentUserInfo
var data = {
UserPoolId: '******************',
ClientId: '******************',
},
userPool = new AWSCognito.CognitoUserPool(data);
var cognitoUser = userPool.getCurrentUser();
AWS.config.region = '******************';
Vue.use(Vuex);
const weatherService = {
state: () => ({
error: null,
currentTemp: '',
minTemp: '',
maxTemp: '',
sunrise: '',
sunset: '',
pressure: '',
humidity: '',
wind: '',
overcast: '',
name: '',
latitude: '',
longitude: '',
}),
mutations: {
SET_WEATHER_DATA(state, payload) {
state.currentTemp = payload.main.temp;
state.minTemp = payload.main.temp_min + '°C';
state.maxTemp = payload.main.temp_max + '°C';
state.pressure = payload.main.pressure + 'hPa';
state.humidity = payload.main.humidity + '%';
state.wind = payload.wind.speed + 'm/s';
state.overcast = payload.weather[0].description;
state.sunrise = new Date(payload.sys.sunrise * 1000)
.toLocaleTimeString('en-GB')
.slice(0, 5);
state.sunset = new Date(payload.sys.sunset * 1000)
.toLocaleTimeString('en-GB')
.slice(0, 5);
state.name = payload.name;
},
},
actions: {
getWeather({
commit
}) {
try {
if (cognitoUser != null) {
cognitoUser.getSession(function(err, session) {
if (err) {
console.log(err);
return;
}
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: '******************',
Logins: {
// Change the key below according to the specific region your user pool is in.
'cognito-idp.******************.amazonaws.com/******************': session
.getIdToken()
.getJwtToken(),
},
});
AWS.config.credentials.get(function(err) {
if (!err) {
var id = AWS.config.credentials.identityId;
// Instantiate aws sdk service objects now that the credentials have been updated
var docClient = new AWS.DynamoDB.DocumentClient({
region: AWS.config.region,
});
var params = {
//
};
params.ProjectionExpression = "user_meta_data";
docClient.query(params, function(err, data) {
if (err) console.error(err);
else {
console.log(data);
const lat = data.Items[0].user_meta_data.coordinates.latitude
const long = data.Items[0].user_meta_data.coordinates.longitude
axios
.get(
'https://api.openweathermap.org/data/2.5/weather?lat=' +
lat +
'&lon=' +
long +
'&units=metric&APPID=' +
process.env.VUE_APP_OPEN_WEATHER_API_KEY
)
.then((response) => {
commit('SET_WEATHER_DATA', response.data)
console.log("dispatched!")
})
.catch((error) => {
console.log(error);
});
}
});
}
});
});
}
} catch (e) {
console.log(e);
return;
}
}
},
getters: {
weatherGetter(state) {
return state
},
},
};
const store = new Vuex.Store({
modules: {
w: weatherService
},
state: {
//
},
mutations: {
//
},
actions: {
//
},
getters: {
//
},
});
export default store;
Weather.vue 组件
<template>
<!-- <div>
<v-card> {{ weatherGetter }} </v-card>
</div>
</template>
<script>
export default {
data() {
return {
};
},
computed: {
weatherGetter() {
return this.$store.getters('weatherGetter');
},
},
mounted() {
this.$store.dispatch('getWeather');
};
</script>
我查看了其他类似的问题,他们似乎建议使用 beforeRouteEnter,我认为这在我的情况下并不理想。我还尝试在 main.js 中创建的钩子中调度操作,但无济于事。
解决方案
这能解决您的问题吗?
<template>
<div v-if="weatherGetter">
<v-card> {{ weatherGetter }} </v-card>
</div>
</template>
推荐阅读
- node.js - 连接 NodeJS 和 SQL Server 时出错 - 无法连接(序列)
- recharts - Recharts:为轴设置等比
- json - 将带有权重的 keras 模型保存到 JSON 文件
- c# - 我是否需要调用“文件流”类来加密文件中的数据?
- python - 使用不同的外键连接多个连接 sqlalchemy python
- javascript - header in react navigation bottom tabs
- vba - 如何让我的 VBA 代码看起来更好并减少冗余?
- python - “加权”用于进程的 SimPy 资源量
- r - geom_bar 两个数据集一起在 R
- c - 代码块 IDE 流畅运行与 Google Kickstart 平台运行时错误