目录:
前言:不知道大家有没有遇到这样的情况,A组件需要v-model绑定一个依赖于Vuex的数据,通常会直接绑定至Vuex数据源,如下所示是正常的处理流程;
data:
--------
trimesterId: "", //学期ID
--------
computed: {
Term() {
return this.$store.state.Term; //返回Vuex依赖值
}
},
--------
mounted() {
this.Search.trimesterId = this.Term[0].value; //赋初始值
},
问题:
但是如果我们的Vuex数据源是异步请求的,那么就会遇到Vuex数据还没有拿到,我们的组件已经被渲染了,如下两种情况:
①:刷新当前页面,并没有显示初始绑定值;
②:从其他页面进入当前页面时,显示正确!
思考:
第一种情况:刷新页面的时候我们的Vuex也会随之重新获取数据,这里面包括所有actions的异步请求数据,当刷新页面的时候组件获取到的state的值为空,也就是说组件在异步完成之前就已经完成渲染了,导致组件的数据没有来得及渲染。
第二种情况:首先应该想到的是Vuex的状态是什么时候获取到的?答案肯定是created生命周期获取的,当从另一页面进入当前页面时,Vuex数据已经加载完毕、当前组件的依赖值已经存在,所以显示正常;
思路:
我们最终的效果肯定是需要无论是刷新还是跳转,都必须赋初始值并正常显示下拉内容,那么Vue的watch监听就可以拿来做这件事情,关于watch我们通常监听data里存在的数据,但依旧可以监听被computed监听的数据,当computed的返回值拿到之后,watch也会监听到computed变化,当computed变化我们把发生变化的值传递给watch,通过watch改变data的初始值,这样当你刷新页面时,Vuex重新触发,随之computed也会监听得到,通过watch赋初始值;
---- data ----
trimesterId: "", //学期ID
--------
computed: {
Term() {
return this.$store.state.Term; //返回Vuex依赖值
}
},
--------
mounted() {
this.Search.trimesterId = this.Term[0].value; //赋初始值
},
---- watch ----
Term(val) {
this.Search.trimesterId = val[0].value; //赋初始值
}
解决关键点:
computed:返回Vuex中依赖数据源;
mounted:在Vuex获取到值以后 赋值给v-model绑定的数据原;
watch:监听computed是否拿到返回值,拿到之后递给v-model绑定;
PS:
其实出现这个问题其根本就是异步问题,渲染提前、数据随后(粮草未动、兵马先行),但开发中如果不使用Vuex,这样的问题我们完全可以使用promise很好的解决,但如果使用settimeout去延迟渲染,本地开发不考虑网速、响应等原因,上线后网速多差谁也不知道,所以settimeout不管你写多长时间的延迟也都是会存在很大问题的,不推荐!