iview-页面复用时根据路由参数刷新数据

141 阅读1分钟

在用iview的时候用到一个交互页面的新增编辑查看页面都一样,所以决定共用一个页面,直接设置了一个opentype参数来区别不同的打开方式(show/edit/new),页面做好后发现有个问题,就是新开一个编辑页面的时候显示的数据仍然是上一个id的数据,新开页面也是这样。可能是iview设置了keep-alive,页面数据被缓存了,没有触发拉取数据的接口。

所以考虑用监听路由的方式,在钩子函数中根据id的变化自动拉取数据。

参考vue路由守卫,主要用到beforeRouteEnter和beforeRouteUpdate这两个钩子函数。

在新开标签页的时候,会触发beforeRouteEnter,这时候并木有构建dom,不能调用this,但是可以用next的回调函数解决。

在已有标签页之间切换的时候,不会触发beforeRouteEnter,会触发beforeRouteUpdate

再用watch监听id变化,如果id更新了就调接口

    watch: {
        id: {
            handler(newval) {
                // console.log('wat-id',newval)
                if(this.id){
                    this.getDetail()
                }else {
                    this.clearData()
                }
            }
        }
    },


    beforeRouteEnter(to,from,next){
        const id = to.query.bannerId
        next((vm) => {
            //直接vm.id的话不触发watch
            if(id){
                vm.id = id
                vm.getDetail()
            }else{
                vm.clearData()
            }
        })
        next()
    },
    beforeRouteUpdate(to,from,next){
        this.id = to.query.bannerId
        next()
    },

在beforeRouteEnter钩子函数中如果只设置vm.id=id,期望在watch函数中监听到id的变化,有时候行不通,所以把更新数据的方法提前放到next回调里。不管是beforeRouteEnter还是beforeRouteUpdate,next()方法必须被调用,否则程序走不下去。

后续

取消用watch监听

	beforeRouteEnter(to,from,next){
		const id = to.query.bannerId
		next((vm) => {
			//直接vm.id的话不触发watch
			vm.id = id
			if(id){
				vm.getDetail()
			}else{
				vm.clearData()
			}
		})
		next()
	},
	beforeRouteUpdate(to,from,next){
		this.id = to.query.bannerId
		if(this.id){
			this.getDetail()
		}else {
			this.clearData()
		}
		next()
	},