javascript - 在 Vuex 中完成操作后从 store 中调用组件函数
问题描述
一旦添加了新元素,我试图自动滚动到包含元素列表的 div 的底部。
由于添加和删除元素是通过 Axios 使用 API 完成的,因此我必须等待来自服务器的响应才能更新我在 Vuex 中的状态。
这意味着,一旦在我的状态中添加了一个元素,每次我调用“scrollDown”函数时,该函数都会滚动到倒数第二个元素(由于尚未注册异步 Axios 调用)。
我的问题是,如何等待 Vuex 中的操作完成,然后调用组件中的函数滚动到 div 的底部?
我尝试使用观察者、计算属性、发送道具、跟踪 Vuex 中实际状态的变化,但这些都不起作用......
// VUEX
const state = {
visitors: [],
url: 'API URL',
errors: []
}
const mutations = {
ADD_VISITOR(state, response) {
const data = response.data;
data.Photos = [];
state.visitors.data.push(data);
},
}
const actions = {
addVisitor: ({ commit }, insertion) => {
axios
.post(state.url + 'api/visitor', {
name: insertion.visitorName
})
.then(response => {
commit('ADD_VISITOR', response);
})
.catch(error => state.errors.push(error.response.data.message));
state.errors = [];
},
}
// MY COMPONENT FROM WHERE THE ACTIONS ARE BEING DISPATCHED
<div ref="scroll" class="visitors-scroll">
<ul v-if="visitors.data && visitors.data.length > 0" class="list-group visitors-panel">
<!-- Displaying appVisitor component and sending data as a prop -->
<app-visitor v-for="visitor in visitors.data" :key="visitor.id" :visitor="visitor"></app-visitor>
</ul>
</div>
methods: {
// Function that dispatches the "addVisitor" action to add a new visitor to the database
newVisitor() {
const insertion = {
visitorName: this.name
};
if (insertion.visitorName.trim() == "") {
this.errors.push("Enter a valid name!");
} else {
this.$store.dispatch("addVisitor", insertion);
this.name = "";
}
this.errors = [];
this.scrollDown(); // I WANT TO CALL THIS FUNCTION WHEN AXIOS CALL IS FINISHED AND MUTATION IN VUEX IS COMPLETED
},
scrollDown() {
this.$refs.scroll.scrollTop = this.$refs.scroll.scrollHeight;
}
},
任何帮助表示赞赏!
解决方案
在 vuex 中调度的动作返回一个 Promise。如果您的代码是空的 Promise,因为没有什么可以返回。您需要返回/传递您的 axios Promise,然后在您的组件中等待它。看看这个固定的代码:
// VUEX
const state = {
visitors: [],
url: 'API URL',
errors: []
}
const mutations = {
ADD_VISITOR(state, response) {
const data = response.data;
data.Photos = [];
state.visitors.data.push(data);
},
}
const actions = {
addVisitor: ({ commit }, insertion) => {
return axios
.post(state.url + 'api/visitor', {
name: insertion.visitorName
})
.then(response => {
commit('ADD_VISITOR', response);
})
.catch(error => state.errors.push(error.response.data.message));
state.errors = [];
},
}
// MY COMPONENT FROM WHERE THE ACTIONS ARE BEING DISPATCHED
<div ref="scroll" class="visitors-scroll">
<ul v-if="visitors.data && visitors.data.length > 0" class="list-group visitors-panel">
<!-- Displaying appVisitor component and sending data as a prop -->
<app-visitor v-for="visitor in visitors.data" :key="visitor.id" :visitor="visitor"></app-visitor>
</ul>
</div>
methods: {
// Function that dispatches the "addVisitor" action to add a new visitor to the database
newVisitor() {
const insertion = {
visitorName: this.name
};
if (insertion.visitorName.trim() == "") {
this.errors.push("Enter a valid name!");
} else {
this.$store.dispatch("addVisitor", insertion)
.then(() => {
this.scrollDown();
})
this.name = "";
}
this.errors = [];
},
scrollDown() {
this.$refs.scroll.scrollTop = this.$refs.scroll.scrollHeight;
}
},
推荐阅读
- matlab - 给定一个 x 坐标,如何从具有该 x 坐标的线数组中删除一条线
- javascript - splice() 的问题,当我只想单个元素时,它返回一个包含单个元素的数组
- r - r - 如何删除 DT::datatable 中标题和正文之间的水平线
- jquery - 如何将每个元素包装在带有属性的标签中?
- google-chrome-devtools - 使用 Chrome 开发工具编辑页面的 CSS 后,我可以查看我所做的具体更改吗?
- flutter - 在 SearchDelegate 中显示 Snackbar
- android - IllegalStateException:已添加的片段未使用 try-catch 捕获
- javascript - 如何使用简单的循环和“if”语句显示数组对象?
- reactjs - Formik 字段包装器
- javascript - Javascript,编写 if 条件的更好方法