uni-app 一个自定义组件被多个页面引用并传值的坑

因为自已要学着做个uniapp项目,我用vue2搞一个音乐微信小程序,在搞到传值的时候给我整不会了,我以为简单的绑定一下要动态改变的属性,然后就通过更新变量就能动态改变属性了,没想到搞了半天才搞明白,我搞的是绑定src

因为是音乐小程序所以我有个自定义的音乐播放栏,就先搞了两个页面,两个页面都放进了uniapp的原生tabbar里面,然后点击这个音乐播放栏进入音乐播放界面,这个点击事件我是用navigateTo直接跳到音乐播放界面的,然后用navigateBack返回上一级页面,很合理对吧。

然后,我每个页面都要有个判断当前音乐播放状态的变量吧,关键是直接我直接调用对象然后获取音乐状态复制后发现这个赋值有时候在my页面有用,有时候又在index有用,就是不能一起生效。

想起来了,微信小程序的组件在不同页面被同一个组件引用时的值并不是通用的,我想uniapp应该微信小程序开发的话也应该有所相同,就想通过父组件(也就是当前页面)向子组件(子组件就是引用的组件)传参来更改,这样即便值不相同,每次传的值是一样的也就没什么不同了

我用的是getBackgroundAudioManager,直接封装在main.js然后就可以在全局vue使用)

// #ifndef VUE3
import Vue, { Static } from 'vue'
import App from './App'
import store from './store'

Vue.config.productionTip = false
Vue.prototype.$music = function (src,title,songer,imgUrl) {
  this.$store.commit('setSong_play_static',false)
	let aa=uni.getBackgroundAudioManager();
  aa.src=src
  aa.title=title
  aa.singer=songer
  aa.coverImgUrl=imgUrl
  aa.startTime=0
  aa.play()
  if(this.$store.state.music_loop =='loop_one'){
    aa.onEnded(()=>{  //循环播放
      this.$store.commit('setSong_play_static',false)
      aa.src=src
      aa.title=title
      aa.singer=songer
      aa.coverImgUrl=imgUrl
      aa.startTime=0
      aa.play()
    })
    
  }else if(this.$store.state.music_loop =='random'){
    //等api再写
  }else if(this.$store.state.music_loop =='loop_list'){
    //等api再写
  }
}

App.mpType = 'app'

const app = new Vue({
  store,
  ...App
})

app.$mount()

为了方便,我又搞了个vuex,确实方便了.

然后一到页面传输就碰坑,两个tabbat页面之间传值,我最开始以为在页面上写onLoad或者mounted在里面获取当前背景音乐对象的播放状态,然后传入子组件,没想到没用,

  

于是上网找了一下,找到了个触发全局的自定义事件

//使用uni.$emit传递事件,第一个参数是事件名
//第二个参数是要传输的对象 object类型
//官网$emit地址https://uniapp.dcloud.net.cn/api/window/communication.html#emit
uni.$emit('music_static',120)
//监听全局的自定义事件,事件由 uni.$emit 触发 
//例如:
uni.$on('music_static', function(result){
    console.log(result)
})

发现没用,怪了,我用console.log()排除选项找到了错误,发现页面的mounted方法只在选然后触发了一次就不触发了,然后我就又去找了个onTabItemTap,这样每次点击这两个tabbar页面都能传参数了

最后发现用onShow就行


 onTabItemTap(){   //当前页面属于tabbar页面并被点击时的事件
   let aa=uni.getBackgroundAudioManager();
   uni.$emit('music_static',aa.paused)
   console.log("点击了tabbar")
 }

后来因为我搞了vuex做变量却发现vuex中的变量只在最初给一次值,变量的值更改后页面里对应的值却不更新,搞的页面逻辑混乱。


最后我就在音乐播放界面使用了循环赋值,另外两个tabbar页面因为使用同一个组件,我就把组件里的vuex变量全删了,只通过其他页面传参进来看要不要改参数。

因为要搞音乐进度条,最后要动态绑定的全都在data先定义个变量绑上去,好在循环的时候赋值更改变量,这样页面就能更新了。

然后发现tabbar页面传参没问题,但是点击进入播放器再出来就没有参数传进tabbar页面,就有问题了,

  onClickLeft() {
    uni.$emit("clickLeft", this.song_static);
    setTimeout(()=>{
      uni.navigateBack()
    },300)
    console.log("left")
  }

我就搞了半天试了循环,初始化刷新都没用,于是就懵逼了,后来还是发现vuex变量是被传来的参数,但我vuex变量改了它还是不变,我才发现搞错了,没删干净,还是用了$emit成功传参,然后又发现直接传参数到页面还不行,要直接传递到子组件里,我也是吐血了,搞了老久了,

    mounted() {
       let aa=uni.getBackgroundAudioManager();
       this.song_play_static=aa.paused
       uni.$emit('music_static',aa.paused)
       uni.$on('clickLeft',(res)=>{  //监听事件
         uni.$emit('music_page',res) //再自定义一个事件传递到子组件中
       })
    }

你可能感兴趣的:(uni-app,微信小程序,前端)