父组件:Collection.vue
子组件:List.vue
引入方式:动态引入
项目中有这样一个场景,从客户列表点入查看详情,将数据缓存进入了store中;从详情页退回到列表,再点入另一个查看详情,导致页面最先渲染前一个页面详情的数据。
凶手就是从computed中求取store中的数据,因为有缓存所以先进行了渲染。然后才会执行mounted中的新的请求再进行替换。
这样就会造成两个现象:
第一,页面中使用了指令,会导致先报一轮错误;
第二,一旦请求回来的太慢,会导致先看到原来的数据;
谜底揭开了,咋改呢?
简介
在一个vue2.0搭建起来的项目里,用了store存储数据,但遇到了一个从列表进入不同详情页的问题。
这个项目简单来说,类似在navicat里,查看mongodb的库和表。
问题
列表页——List.vue
详情页——Detail.vue
<template>
<div id="detail">
<my-component :bucketName="bucketName" :dbName="dbName" :clName="clName"></my-component>
</div>
</template>
<script>
export default {
name: 'Detail',
props: {
bucketName: String,
dbName: String,
clName: String
},
components: {
//这采用的动态引入,是由于项目需要
'my-component': () => import('../../../ue_comp/src/Comp.vue')
}
}
</script>
详情页组件——Comp.vue
<template>
<div class="comp">
<el-table id="table" :data="documents" ref="documentsTable" :max-height="250">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column v-for="(s, k) in properties" :key="k" :prop="k">
<template slot="header">
<span>{{ s.title }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import store from '../../ue_mongo/src/store'
const componentOptions = {
props: {
bucketName: String,
dbName: String,
clName: String,
tmsAxiosName: {
type: String,
default: 'mongodb-api',
}
},
data() {
return {
properties: {}
}
},
computed: {
documents() {
return store.state.documents
},
},
methods: {
listDocument() {
createDocApi(this.TmsAxios(this.tmsAxiosName))
.list(
this.bucketName,
this.dbName,
this.clName
)
.then((result) => {
const documents = result.docs
store.commit('documents', { documents })
})
},
},
mounted() {
this.listDocument()
}
}
export default componentOptions
</script>
大致代码如上。
从列表页进入A详情页,会将A详情页所需的表头和数据展示出来;再进入B详情页,会将B详情页所需的表头和数据展示出来。
但出现了个问题,就是当再进入B时,会先将A详情页的数据展示出来,而后才会展示B详情页的。
分析
由于Comp组件是被动态引入的子组件,因此访问完A页面就将A的数据缓存进入了store中。
而且vue中,执行顺序是这样的:created -> computed -> mounted。
因此,当进入B页面时,会先取出store中的数据,然后再去获取B应该展示的数据。
解决
我采用的办法是,在Comp组件被destory前时,将store中的documents置为空。
beforeDestroy() {
store.commit('documents', { documents: [] })
},
反思
(1)vue页面有异常,但又能正常加载,可能跟声明周期有关;
(2)一个被多次引入的组件,是否该使用store;