uni-app vue 父组件获得子组件data值为undifne

本文探讨了子组件初始化过慢导致父组件无法及时调用其方法的问题。通过使用异步初始化方法并加入等待机制,确保子组件初始化完成后再进行调用,有效解决了此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原因

子组件初始化过慢导致父组件在执行子组件的方法时还没有初始化完成

代码

子组件

created() {
			// 在组件初始化的时候执行,只执行一次
		    if( !this.tableData){
		        this.init(this.tableName,this.tableId);
		    }
			console.log(this.$data);
			console.log(this.tableData);
		},
		 onReady() {
            console.log( this.$refs.xiangqing.getTableData().xuanjianluxian  );
            console.log( this.$refs.xiangqing.getTableValue('xuanjianluxian') );  
			// this.getData();
		},

解决

		async onReady() {
            // 先手动执行初始化,注意加await等待里面的http请求结束后再继续执行
            await this.$refs.xiangqing.init( this.tableName , this.tableId);
            // 之后就可以获得值了。
            console.log( this.$refs.xiangqing.getTableData().xuanjianluxian  );
            console.log( this.$refs.xiangqing.getTableValue('xuanjianluxian') );  
			// this.getData();
		},
<think>我们将在uni-appvue2中封装mescroll-uni组件。mescroll-uni是一个用于实现下拉刷新和上拉加载的组件,在uni-app项目中非常常用。封装该组件可以提高代码复用性,简化页面代码。封装步骤:1.创建组件文件:在components目录下创建mescroll-uni文件夹,并新建mescroll-uni.vue文件。2.编写模板:使用mescroll-uni提供的标签结构,并预留插槽(slot)以便在使用组件时插入自定义内容。3.定义props:根据mescroll-uni的配置选项,定义组件的props,允许父组件传递配置参数。4.实现事件处理:处理下拉刷新和上拉加载的事件,并触发父组件的事件回调。5.暴露方法:通过ref可以调用组件内部的方法,如重置滚动条、结束加载等。下面是一个封装示例:文件路径:`/components/mescroll-uni/mescroll-uni.vue````vue<template><mescroll-uniref="mescrollRef":top="top":bottom="bottom"@init="mescrollInit"@down="downCallback"@up="upCallback"><!--内容插槽--><slot></slot></mescroll-uni></template><script>//引入mescroll-uniimportMescrollUnifrom'mescroll-uni/mescroll-uni.vue'exportdefault{components:{MescrollUni},props:{top:{type:[String,Number],default:0},bottom:{type:[String,Number],default:0},//其他mescroll配置项可以根据需要添加//例如:是否启用下拉刷新、上拉加载等downOption:{type:Object,default:()=>({auto:true,//是否在初始化后自动执行下拉回调callback:null//下拉刷新的回调函数,由父组件传递})},upOption:{type:Object,default:()=>({auto:true,//是否在初始化后自动执行上拉回调callback:null//上拉加载的回调函数,由父组件传递})}},data(){return{mescroll:null//mescroll实例}},methods:{//mescroll初始化mescrollInit(mescroll){this.mescroll=mescroll},//下拉刷新回调downCallback(){//如果父组件传递了下拉刷新的回调函数,则执行if(this.downOption.callback){this.downOption.callback().then(()=>{//结束下拉刷新this.mescroll.endSuccess()}).catch(()=>{//结束下拉刷新(失败)this.mescroll.endErr()})}else{//如果没有传递回调,则直接结束下拉刷新this.mescroll.endSuccess()}},//上拉加载回调upCallback(){if(this.upOption.callback){this.upOption.callback().then((hasMore)=>{//结束上拉加载if(hasMore){this.mescroll.endSuccess()}else{this.mescroll.endSuccess(0)//无更多数据}}).catch(()=>{this.mescroll.endErr()})}else{this.mescroll.endSuccess()}},//重置滚动条(提供给父组件使用)reset(){this.mescroll.resetUpScroll()},//结束下拉刷新和上拉加载(提供给父组件调用)endPullDown(){this.mescroll.endDownScroll()},endPullUp(){this.mescroll.endUpScroll()}}}</script><style>/*可以在这里覆盖mescroll的默认样式,或者不写,使用默认样式*/</style>```使用示例(在页面中):```vue<template><view><!--封装后的mescroll组件--><mescroll-wrapperref="mescroll":down-option="downOption":up-option="upOption"><!--你的列表内容--><viewv-for="(item,index)inlist":key="index">{{item}}</view></mescroll-wrapper></view></template><script>importMescrollWrapperfrom'@/components/mescroll-uni/mescroll-uni.vue'exportdefault{components:{MescrollWrapper},data(){return{list:[],//列表数据downOption:{callback:this.downCallback//下拉刷新回调},upOption:{callback:this.upCallback//上拉加载回调}}},methods:{//下拉刷新回调downCallback(){returnnewPromise((resolve)=>{//模拟请求setTimeout(()=>{this.list=[1,2,3,4,5]//重置列表resolve()},1000)})},//上拉加载回调upCallback(){returnnewPromise((resolve)=>{setTimeout(()=>{//模拟加载下一页constnewList=Array.from({length:5},(_,i)=>this.list.length+i+1)this.list=[...this.list,...newList]//假设还有更多数据,则传递true;否则falseconsthasMore=this.list.length<20resolve(hasMore)},1000)})}}}</script>```注意:1.我们通过props将mescroll的配置项传递给组件,特别是downOption和upOption中的callback,用于下拉刷新和上拉加载的业务逻辑。2.在组件内部,我们通过调用mescroll实例的方法(如endSuccess,endErr,resetUpScroll等)来控制mescroll的状态。3.通过ref可以调用组件暴露的方法,例如在页面中需要手动触发刷新时,可以调用`this.$refs.mescroll.reset()`。这样封装后,在多个页面使用mescroll-uni组件时,可以避免重复代码,并且统一管理下拉刷新和上拉加载的逻辑。§§相关问题§§1.如何在封装mescroll-uni组件时处理不同页面的特殊需求?2.mescroll-uni组件封装后,如何实现页面滚动到指定位置?3.在uni-app中,如何全局注册mescroll-uni封装组件?</think>### 在 uni-appVue2 中封装 mescroll-uni 组件 mescroll-uniuni-app 生态中常用的下拉刷新/上拉加载组件。以下是完整的封装实现方案: #### 封装步骤 1. **创建组件文件** 在 `components` 目录下创建 `mescroll-wrapper` 组件: ``` /components /mescroll-wrapper └── mescroll-wrapper.vue ``` 2. **组件封装代码** ```vue <!-- components/mescroll-wrapper/mescroll-wrapper.vue --> <template> <mescroll-uni ref="mescrollRef" :down="downOption" :up="upOption" @down="onDown" @up="onUp" > <!-- 内容插槽 --> <slot></slot> </mescroll-uni> </template> <script> export default { props: { // 下拉刷新配置 downOption: { type: Object, default: () => ({ auto: true, // 自动触发下拉刷新 textLoading: '加载中...' }) }, // 上拉加载配置 upOption: { type: Object, default: () => ({ auto: true, // 自动触发上拉加载 noMoreSize: 5, // 剩余条数不足时触发 textLoading: '正在加载...', textNoMore: '-- END --' }) } }, methods: { // 下拉刷新回调 onDown() { this.$emit('down', (success = true) => { this.$refs.mescrollRef.endDownScroll(success) }) }, // 上拉加载回调 onUp(page) { this.$emit('up', page, (success, hasMore) => { this.$refs.mescrollRef.endUpScroll(success, hasMore) }) }, // 重置滚动 (暴露给父组件) reset() { this.$refs.mescrollRef.resetUpScroll() } } } </script> ``` 3. **页面中使用示例** ```vue <template> <view> <mescroll-wrapper ref="mescroll" :down-option="{ use: true }" :up-option="{ page: { size: 10 } }" @down="onRefresh" @up="loadData" > <!-- 列表内容 --> <view v-for="item in list" :key="item.id"> {{ item.name }} </view> </mescroll-wrapper> </view> </template> <script> import MescrollWrapper from '@/components/mescroll-wrapper/mescroll-wrapper.vue' export default { components: { MescrollWrapper }, data() { return { list: [], pageNum: 1 } }, methods: { // 下拉刷新 onRefresh(endDownScroll) { this.pageNum = 1 this.loadData(1, (success, hasMore) => { endDownScroll(success) }) }, // 上拉加载 loadData(page, endUpScroll) { const pageSize = 10 // 模拟API请求 uni.request({ url: '/api/list', data: { page, pageSize }, success: (res) => { if (page === 1) this.list = [] this.list = [...this.list, ...res.data] // 结束加载状态 const hasMore = res.data.length >= pageSize endUpScroll(true, hasMore) } }) }, // 手动触发刷新 manualRefresh() { this.$refs.mescroll.reset() } } } </script> ``` #### 关键特性说明 1. **插槽设计** 通过 `<slot>` 实现内容区域完全自定义,支持任意列表布局 2. **事件传递机制** - `@down`:下拉刷新事件,返回结束函数 - `@up`:上拉加载事件,返回页码和结束函数 - 结束函数需手动调用以更新组件状态 3. **方法暴露** - `reset()` 方法允许父组件主动触发刷新 - 通过 `ref` 可访问原生 mescroll 实例 4. **配置继承** 所有原生 mescroll-uni 的[配置项](https://www.mescroll.com/uni.html)均可通过 `downOption`/`upOption` 传递 #### 优化建议 1. **全局注册组件**(可选) 在 `main.js` 中全局注册: ```javascript import MescrollWrapper from '@/components/mescroll-wrapper' Vue.component('mescroll-wrapper', MescrollWrapper) ``` 2. **网络错误处理** 在加载回调中添加错误处理: ```javascript endUpScroll(false) // 传递 false 表示加载失败 ``` 3. **空数据状态** 配合插槽实现空数据提示: ```vue <mescroll-wrapper> <template v-if="list.length>0"> <!-- 列表内容 --> </template> <empty-state v-else /> </mescroll-wrapper> ``` 4. **兼容性处理** 使用 `this.$nextTick` 确保 DOM 更新后操作: ```javascript this.$nextTick(() => { this.$refs.mescroll.reset() }) ``` 这种封装方式实现了: ✅ 配置与业务逻辑分离 ✅ 统一的下拉/上拉处理逻辑 ✅ 跨页面复用能力 ✅ 完整的生命周期控制 ✅ 原生组件功能无损传递 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值