Vue怎么实现父子组件页面刷新(vue,开发技术)

时间:2024-05-04 09:11:54 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

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

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

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

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

2、空白页面作为过渡

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

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

//引入空白页面组件importemptyfrom'@/views/organization/empty.vue'//添加路由跳转this.$router.replace({path:'/empty'});

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

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

详情参考官网指导文档。

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

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

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

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

<template><divid="app"><router-viewv-if="isShow"/></div></template><script> exportdefault{ name:'App', provide(){//父组件中通过provide来提供变量,在子组件中通过inject来注入变量。 return{ reload:this.reload } }, data(){ return{ isShow:true//控制视图是否显示的变量 } }, methods:{ reload(){ this.isShow=false;//先关闭 this.$nextTick(()=>{ this.isShow=true//再打开 }) } } }</script>

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

<template><div><divclass="header"><button@click="update()">刷新页面</button></div></div></template><script> exportdefault{ data(){ return{ } }, inject:['reload'],//inject注入根组件的reload方法 methods:{ update(){ this.reload(); console.log('刷新页面') } } }</script>

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

<template><divid="app"><router-viewv-if="isRouterAlive"/></div></template><scriptlang="ts">import{Component,Vue}from'vue-property-decorator'@Component({name:'App',provide(){//父组件中通过provide来提供变量,在子组件中通过inject来注入变量。reload:this.reload},data(){return{isRouterAlive:true//控制视图是否显示的变量}},method:{reload(){this.isRouterAlive=false//先关闭this.$nextTick(()=>{this.isRouterAlive=true//再打开})}}})exportdefaultclassextendsVue{}</script>

子组件中注入reload:

<scriptlang="ts">import{updateStore,//更新门店信息getStoresData,//获取门店列表信息searchStore//根据门店id和商户id获取门店信息}from'@/api/organization.ts'importAppfrom'@/App.vue'@Component({components:{updateStore,getStoresData,searchStore}}) /***此处的默认输出是集成Vue类(和java中定义实体类跟相似)*/exportdefaultclasscreateTasksextendsVue{ //此处注入relod inject:['reload']; privateasyncensureDialog(){letres=awaitupdateStore(this.form)this.syncDialogVisible=false;if(res){this.$message.success('修改成功');}//到达此处说明请求响应成功this.reload();//此处调用根组件的reload方法} }

上述做法不生效,如果有大神知道哪个不对,还望不吝赐教。

4、v-on:param父组件监听子组件事件

我们知道Vue有一个特点,只要vue实例中的数据属性值发生改变,页面中使用v-model或者:data渲染绑定的数据也会随之改变,通常情况下展示数据的界面为父组件,需要对父组件中的某一条数据进行增删改查操作时,都会响应弹出一个组件框悬浮在父组件之上单独展示某一条数据的内容,而这个悬浮组件就可以看做是子组件。

所以我们只要在父组件中监听到子组件的行为事件,就可以在进行当前页面的局部数据刷新(非重新加载)。

父组件:index.vue

<template><divclass="data-container"><h4>门店管理</h4><el-table:data="list"fithighlight-current-row:header-cell-> </el-table> <addStore:dialogVisible.sync="dialogVisible"v-on:post="getList"@refreshList="getList"></addStore> <setCode:dialogVisible.sync="dialogVisible1"@refreshList="getList":code="codes"></setCode> <updateStore:dialogVisible.sync="dialogVisible2"v-on:put="getList"@refreshList="getList":storeIds="storeId"></updateStore> <setUse:dialogVisible.sync="dialogVisible3"@refreshList="getList"@getAppId="getAppIds"></setUse> <paginationv-show="total>0":total="total":page.sync="pageNo":limit.sync="pageSize"@pagination="getList"/> </div></template><scriptlang="ts">importaddStorefrom'@/views/organization/addStore.vue'importPaginationfrom"@/components/Pagination/index.vue";importsetCodefrom'@/views/organization/setCode.vue'importupdateStorefrom'@/views/organization/updateStore.vue'importsetUsefrom'@/views/organization/setUse.vue'@Component({components:{addStore,Pagination,setCode,updateStore,setUse}})exportdefaultclassextendsVue{privatelist:any[]=[];privatepageNo:number=1;privatepageSize:number=10;privatetotal:number=0;privatedialogVisible:boolean=false;privatedialogVisible1:boolean=false;privatedialogVisible2:boolean=false;privatedialogVisible3:boolean=false;privateappId:string='';privatecodes:string='';privatestoreId:string='';privatestoreForm={storeName:'',storeNumber:''}privateform={totalAmount:'',body:''}created(){this.getList()}privateasyncgetList(){letdata=awaitgetStoresData(this.pageNo,this.pageSize,this.storeForm)this.list=data.items;//查询到的门店列表this.total=this.list.length;//查询到的总记录数}}</script>

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

//新增门店子组件<addStore:dialogVisible.sync="dialogVisible"v-on:post="getList"@refreshList="getList"></addStore>//更新门店子组件<updateStore:dialogVisible.sync="dialogVisible2"v-on:put="getList"@refreshList="getList":storeIds="storeId"></updateStore>

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

privateasyncgetList(){letdata=awaitgetStoresData(this.pageNo,this.pageSize,this.storeForm)this.list=data.items;//查询到的门店列表}

getStoresData方法:

//分页条件查询商户下门店exportconstgetStoresData=(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;//查询到的门店列表<el-table:data="list"fithighlight-current-row:header-cell-></el-table>

更新数据子组件updaStore.vue:

<template><el-dialogtitle="修改门店信息":visible.sync="syncDialogVisible"@open="opend"><el-form:inline="false"><el-form-itemlabel="门店名称:":label-width="formLabelWidth":rules="[{required:true}]"><el-inputv-model="form.storeName"></el-input></el-form-item><el-form-itemlabel="门店地址:":label-width="formLabelWidth"><el-inputv-model="form.storeAddress"></el-input></el-form-item><el-form-itemlabel="门店编号:":label-width="formLabelWidth"><el-inputv-model="form.storeNumber"></el-input></el-form-item></el-form><divslot="footer"class="dialog-footer"><el-button@click="syncDialogVisible=false">取消</el-button><el-buttontype="primary"@click="ensureDialog">确定</el-button></div></el-dialog></template><scriptlang="ts">@Component({components:{updateStore,getStoresData,searchStore}})exportdefaultclasscreateTasksextendsVue{@PropSync('dialogVisible',{type:Boolean,default:false})syncDialogVisible!:boolean@PropSync('storeIds',{type:String})storeId!:stringprivateform={id:0,storeAddress:'',storeName:'',storeNumber:0,parentId:0,storeStatus:'',merchantId:0}privatestoreForm={storeNumber:'',storeName:''}list:any[]=[];pageNo:number=1;pageSize:number=10;total:number=0;privatefilterData:any[]=[];privateopend(){this.getList();}privateasyncgetList(){letres=awaitsearchStore(this.storeId);this.form=res.result; }privateasyncensureDialog(){letres=awaitupdateStore(this.form)this.syncDialogVisible=false;if(res){this.$message.success('修改成功');}}}</script>

实际应用场景:

Vue怎么实现父子组件页面刷新

Vue怎么实现父子组件页面刷新

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

privateasyncensureDialog(){letres=awaitupdateStore(this.form)this.syncDialogVisible=false;if(res){this.$message.success('修改成功');} //此处查询列表信息letret=awaitgetStoresData(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中:

//更新门店子组件<updateStore:dialogVisible.sync="dialogVisible2"v-on:put="getList"@refreshList="getList":storeIds="storeId"></updateStore>

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

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

  • 子组件直接触发父组件的监听事件,父组件查询列表信息

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

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

privateasyncensureDialog(){letres=awaitupdateStore(this.form)this.syncDialogVisible=false;if(res){this.$message.success('修改成功');}//触发父组件监听事件put this.$emit('put');}
//父组件监听到事件putv-on:put="getList"//调用getList方法重新查询列表信息(此处的this.list就是渲染界面的绑定属性),这样完成数据刷新,而不用重新加载整个页面privateasyncgetList(){letdata=awaitgetStoresData(this.pageNo,this.pageSize,this.storeForm)this.list=data.items;//查询到的门店列表this.total=this.list.length;//查询到的总记录数}

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

privateasyncensureDialog(){letres=awaitupdateStore(this.form)this.syncDialogVisible=false;if(res){this.$message.success('修改成功');} //此处查询列表信息letret=awaitgetStoresData(this.pageNo,this.pageSize,this.storeForm);let=ret.items;=this.list.length;//触发父组件监听事件put,同时传递数据(后面的皆为参数数据) this.$emit('put',ret.items,ret.items.length);}
//父组件监听到事件putv-on:put="getList"//根据子组件传递过来的数据进行同步更新渲染(此方法的参数列表个数要与所监听的事件传递的参数个数保持一致)privateasyncgetList(param1,param2){this.list=param1;//子组件传递过来的列表数据this.total=param2;//子组件传递过来的列表记录数}

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

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Vue怎么实现父子组件页面刷新的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:springboot怎么实现图片大小压缩功能下一篇:

16 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18