Vue实现父子组件页面刷新的几种常用方法

很多时候我们在操作过页面时候,特别是增删改操作之后,数据会有所改变,这个时候我们希望返回的界面中的数据要和数据库中的数据进行同步,就需要刷新当前页面,如果是使用ajax可以使用异步请求实现页面的局部刷新,Vue常用的几种刷新页面方法如下:

1、原地页面重新加载(不推荐)

this.$router.go(0) //根据路由重新定向到当前页
或者
location.reload() //重新加载当前页

上述两种方法可以数据同步,但是其实都是重新加载当前页面,在刷新的时候会出现屏幕闪动,如果当前页面初始化加载的数据或者请求很多的时候,此种方法严重影响效率和体验感。

2、空白页面作为过渡

新建一个空白页面组件empty.vue,点击确定的时候先跳转到这个空白页,然后再立刻跳转回当前页面。

在需要刷新的页面先引入空白页面组件,再添加路由跳转:

//引入空白页面组件
import empty from '@/views/organization/empty.vue'

//添加路由跳转
this.$router.replace({ path:'/empty' });

此种方法基本和上述两种方法,不会出现一瞬间的空白页(如果网络不好或者数据量大也可能会出现),只是地址栏有个快速的切换的过程,如果数据量不大也可以采用。

3、使用Provide / Inject组合控制显示

详情参考官网指导文档。

通常,当我们需要从父组件向子组件传递数据时,我们使用 props。想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,可能会很麻烦。

对于这种情况,我们可以使用一对 provideinject。无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这些数据。

此种方法最基本的Vue脚手架工程很容易实现:

在App.vue跟组件中定义变量和方法如下:




在子组件中使用inject注入根组件的reload方法:




但是我使用的vue项目是基于webpack构建的,整体项目结构有点不同,搞了半天也没搞出来:




子组件中注入reload:


可以看到上述父组件中包含了以下子组件:

//新增门店子组件


//更新门店子组件

getList方法的作用就是更新当前父组件要展示的数据:

private async getList() {
     let data = await getStoresData(this.pageNo, this.pageSize, this.storeForm)
     this.list = data.items; //查询到的门店列表
}            

getStoresData方法:

//分页条件查询商户下门店
  export const getStoresData = (pageNo:number,pageSize:number,data:any) =>
    request({
      url: `/merchant/my/stores/merchants/page?pageNo=${pageNo}&pageSize=${pageSize}&tenantId=${UserModule.tenantId}`,
      method: 'post',
      data
  })

渲染数据:

this.list = data.items; //查询到的门店列表


    

更新数据子组件updaStore.vue:




实际应用场景:

Vue实现父子组件页面刷新的几种常用方法_第1张图片

Vue实现父子组件页面刷新的几种常用方法_第2张图片

在子组件updateStore.vue中,点击确定修改,修改成功之后在当前组件中进行查询门店列表getStoresData:

private async ensureDialog() {
            let res = await updateStore(this.form)
            this.syncDialogVisible = false;
            if (res) {
                this.$message.success('修改成功');
            }
			//此处查询列表信息
            let ret = await getStoresData(this.pageNo, this.pageSize, this.storeForm);
            this.list = ret.items;
            this.total = this.list.length;
        }

按理论是查询到了修改之后的门店列表list,但是当前是在子组件中,list和父组件index.vue中的list作用域不同,所以父组件中的内容也不会发生改变同步更新,那怎么办呢?

上述我们说了,我们需要父组件监听子组件的事件,当子组件完成相应的操作请求之后可以触发父组件所监听的回调函数,让其父组件index.vue实现list的更新,刷新页面中的数据。

在父组件index.vue中:

//更新门店子组件

v-on:put="getList"其中的put就是监听子组件的一个可触发事件,所以我们可以在子组件中完成put更新请求之后,触发该事件,让父组件来完成同步更新渲染数据。

此处完成同步更新有两种方式:

  • 子组件直接触发父组件的监听事件,父组件查询列表信息
  • 子组件将查询好的列表信息,在触发监听事件同时传递给父组件

第一种方式:直接触发监听事件

private async ensureDialog() {
            let res = await updateStore(this.form)
            this.syncDialogVisible = false;
            if (res) {
                this.$message.success('修改成功');
            }
            //触发父组件监听事件put
			this.$emit('put');
        }
//父组件监听到事件put
v-on:put="getList"

//调用getList方法重新查询列表信息(此处的this.list就是渲染界面的绑定属性),这样完成数据刷新,而不用重新加载整个页面
private async getList() {
            let data = await getStoresData(this.pageNo, this.pageSize, this.storeForm)
            this.list = data.items; //查询到的门店列表
            this.total = this.list.length; //查询到的总记录数
        }

第二种方式:触发监听事件的同时传递数据

private async ensureDialog() {
            let res = await updateStore(this.form)
            this.syncDialogVisible = false;
            if (res) {
                this.$message.success('修改成功');
            }
			//此处查询列表信息
            let ret = await getStoresData(this.pageNo, this.pageSize, this.storeForm);
            let = ret.items;
             = this.list.length;
             //触发父组件监听事件put,同时传递数据(后面的皆为参数数据)
			this.$emit('put',ret.items,ret.items.length);
        }
//父组件监听到事件put
v-on:put="getList"

//根据子组件传递过来的数据进行同步更新渲染(此方法的参数列表个数要与所监听的事件传递的参数个数保持一致)
private async getList(param1,param2) {
            this.list = param1; //子组件传递过来的列表数据
            this.total = param2; //子组件传递过来的列表记录数
        }

addStore.vue子组件同样可以用此方法完成同步更新渲染。

参考文档:

$emits选项

Vue组件基础(监听子组件事件)

到此这篇关于Vue实现父子组件页面刷新的几种常用方法的文章就介绍到这了,更多相关Vue 父子组件页面刷新内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

你可能感兴趣的:(Vue实现父子组件页面刷新的几种常用方法)