问题场景:比如两个可切换的tab栏,两个内容框里面用的同一个请求列表的接口和同一个组件,请求列表的参数,除了公共参数之外,(tab2比tab1多两个参数)。
现在遇到的问题1是:
在每次切换tab的时候请求列表的接口都会调用两次,理想的情况是对应的tab栏只调用一次。
解决问题1的思路是:在tab里面的列表组件上添加 v-if:activeName
,因为 el-tab
本身内部是使用 v-show
来显示与隐藏 el-tab-pane
的,所以在每次切换tab的时候接口会调用两次。
问题2:在子组件中修改父组件传递过来的对象,不会触发视图实时更新,监听不到对象的变化,不会触发列表请求接口。
解决问题2思路是:在父组件中定义好公共参数和多余参数的对象search
,然后用 computed
监听 params
,将被序列化后的 JSON.parse(JSON.stringify(search))
赋值给 params
,并在切换到 tab1
组件的时候,从 params
中删除多余的属性。子组件修改父组件中的对象,如果视图不更新,在子组件中调用父组件中定义修改对应属性的方法,使值的更改来自于父对象。
父组件
<el-tabs v-model="activeName"">
<el-tab-pane label="事件1" name="ready">
<EventList v-if="activeName === 'ready'"
:search-params="params" @getSort="searchSort"></EventList>
</el-tab-pane>
<el-tab-pane label="事件2" name="done">
<EventList v-if="activeName === 'done'"
:search-params="params" @getSort="searchSort" @changeSelect="changeSelect"></EventList>
</el-tab-pane>
</el-tabs>
data() {
return {
activeName: 'ready',
date: [],
search: {
start: '',
end: '',
username: 1,
sort: 0,
result: -1,
status: -1
},
}
},
computed: {
params() {
let tmp = JSON.parse(JSON.stringify(this.search))
if (this.activeName === 'ready') {
delete tmp.result
delete tmp.status
}
return tmp
}
},
watch: {
date() {
this.search.start = this.date[0]
this.search.end = this.date[1]
}
},
methods: {
searchSort() {
this.search.sort = this.search.sort ? 0 : 1
},
changeSelect(data) {
this.search[data.label] = data.value
}
}
}
子组件
<el-select size="mini" v-model="searchParams.result" class="w-120" @change="changeSelect(searchParams.result, 'result')">
<el-option label="全部" :value="-1" />
<el-option label="误报" :value="0" />
<el-option label="非误报" :value="1" />
</el-select>
</div>
<span class="pointer search-sort" @click="searchSort">
时间
<i :class="searchParams.sort === 0 ? 'el-icon-bottom' : 'el-icon-top'"></i>
</span>
export default {
props: {
searchParams: {
type: Object,
default: () => {}
}
},
data() {
return {
}
},
methods: {
searchSort() {
this.$emitx('getSort')
},
changeSelect(value, label) {
this.$emitx('changeSelect', { value, label })
}
}
}