这篇文章会介绍父子组件之间,爷爷与孙子之间,不相关组件之间,页面与页面之间,整个项目之间,nvue与vue页面之间,app与H5页面之间的通讯方式。

组件之间通讯

  1. 父传子
    父级通过自定义属性传送给子组件,vue子组件通过props接受,unapp通过onload生命周期的参数接收。
//父组件
<template>
  <div id="app">
  	//第一种静态数据 <HelloWorld msg="我是父组件的数据"/>
    //第二种动态绑定 <HelloWorld :msg="message"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  data(){
    return{
      message: '我来自父组件'
    }
  },
  components: {
    HelloWorld
  }
}
</script>

vue接收

//子组件
<template>
  <div class="hello">
    来自父组件的值:{{msg}}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: ['msg']
  //或者 props: { msg: String//指定传入的类型 }
  //或者 props: { msg: String,default: '默认值' //指定默认值 }
}
</script>

uniapp接收

//子组件
<template>
  <div class="hello">
    来自父组件的值:{{msg}}
  </div>
</template>

<script>
export default {
  data(){
      return data{
      msg: ''
      }
  },
  onLoad(option){
      this.msg = option.msg;
  }
}
</script>
  1. 子传父

子组件给父组件传值通过给父组件定义一个自定义事件,子组件用emit接收,$emit的第一个参数为自定义事件名,第二个参数为传给父组件数据,
父组件通过自定义事件函数中接受的参数拿到子组件传过来的值。

//父组件
<template>
  <div id="app">
    <HelloWorld @getData="message"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  data(){
    return{
      
    }
  },
  methods: {
    message: (data)=>{
      console.log('我是父组件的方法,在子组件中被触发了')
      console.log('来自子组件的值是:'+data)
    }
  },
  components: {
    HelloWorld
  }
}
</script>
//子组件
<template>
  <div class="hello" @click="goFun">
    点击传值给父组件
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      s: 1111
    }
  },
  methods: {
    goFun(){
      this.$emit('getData',this.s)
    }
  }
}
</script>
  1. 爷爷与孙子组件之间传值

通过 $attrs 将值连续往下传递(和props传递类似),传递过程中可以只选择当前需要的值,组件中可以通过 inheritAttrs:false 保持当前组件的属性纯净度。通过 $listeners 可以在(…子组件)中 this. $emit(“upRocket”,11111)来触发父组件中的事件,从而达到传值给父组件的目的。

//父组件
<template>
   <div>
     <child-dom
      :foo="foo"
      :coo="foo"
      @upRocket="reciveRocket"
     >
     </child-dom>
   </div>
</template>
<script>
   import childDom from "./components/ChildDom.vue";
   export default {
     data() {
        return {
          foo:"Hello, world",
          coo:"Hello,rui"
        }
     },
     methods:{
       reciveRocket(data){
          console.log("我是根组件,这是接受的孙子组件的数据"+data)
       }
     },
     components:{childDom},
   }
</script>
//子组件
<template>
   <div>
      <p>foo:{{foo}}</p>
      <childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>
   </div>
</template>
<script>
import childDomChild from './childDomChild';
export default {
 name:'child-dom',
 props:["foo"],
 inheritAttrs:false,
 components:{childDomChild}
}
</script>

//孙子组件
<template>
   <div>
      <p>coo:{{coo}}</p> 
      <button @click="startUpRocket">发送数据到根组件</button>   </div>
</template>
<script>

export default {
 name:'child-dom',
 props:["coo"],
 methods: {
     startUpRocket() {
      this.$emit("upRocket");
     }
  }
}
</script>

  1. 不相关组件之间

全局变量,挂载到vue原型上的EventBus

//组件a
<template>
   <div>
    {{fontCount}}
     <child-dom>
     </child-dom>
   </div>
</template>
<script>
   import { EventBus } from "./assets/bus.js";
   import childDom from "./components/ChildDom.vue";
   export default {
     data() {
       return{
        fontCount: 0
       }
     },
     methods:{
     },
     mounted(){
      EventBus.$on("decreased", ({num}) => {
        this.fontCount -= num
      });
     },
     components:{childDom},
   }
</script>
//组件b
<template>
   <div>
      <button @click="decrease()">-</button>
   </div>
</template>
<script>
import { EventBus } from "../assets/bus.js";
export default {
  name:'child-dom',
  data() {
    return {
      num: 1,
      deg:180
    };
  },
  methods: {
    decrease() {
      EventBus.$emit("decreased", {
        num:this.num
      });
    }
  }
}
</script>

还有就是vuex,内容较多就不给例子了,有兴趣的朋友区vue官网上看文档

  1. 页面与页面之间

页面与页面之间的常用通讯方式就是页面跳转时通过url把参数拼接到地址后面,但这种方式的局限性是参数不能太大,大了就传不了,比如说,要向某个页面传地图中某个面的坐标,这就需要通过定义全局事件来解决。

//页面a
<template>
<view @click="toNextPages">跳转到b页面</view>
</template>
<script>
   export default {
     data() {
       return{
       
       }
     },
     methods:{
         toNextPages(){
         uni.$emit("area",[[132.3434,107.34343],[132.3434,107.3434],
         [132.3434,107.3434], [132.3434,107.3434],[132.3434,107.3434],
         [132.3434,107.3434], [132.3434,107.3434],[132.3434,107.3434],
         [132.3434,107.3434]])
              uni.navigateTo({
                            url: '/pages/tabbar/home/b'
                        })
         }
     }
   }
</script>
//页面b
<template>

</template>
<script>
export default {
  data() {
    return {
    
    };
  },
  onLoad(){
  uni.$on("area",(data)={
  console.log(data);
  })
  }
  methods: {
  
    }
  }
}
</script>
  1. 整个项目之间

之前介绍的EventBus、vuex和自定义事件都能实现整个项目之间通讯,当然除了它们之外,还有本地存储也可以实现。

//页面a
<template>
 <view class="login" @click="login">登录</view>
</template>
<script>
   export default {
     data() {
       return{
       
       }
     },
     methods:{
        // 登录
            login() {
                let vm = this
                uni.showLoading({
                    title: '登录中...'
                });
                vm.utils.sendRequest('api/login', 'POST', {
                    username: vm.username,
                    password: vm.password,
                    code: vm.code
                }, {})
                .then(function(res) {
                	console.log(res.data)
                    if(res.data.code == 200) {
                        uni.hideLoading();
                        uni.showToast({
                            title: '登录成功!',
                            duration: 1000
                        });
                        uni.setStorage({
                            key: 'token',
                            data: res.data.data.access_token,
                            success: function () {}
                        });
                        uni.reLaunch({
                            url: '/pages/tabbar/home'
                        })
                    }else {
                        vm.getVeriCode()
                        uni.showToast({
                            title: res.data.data,
                            duration: 1000,
                            icon: 'none'
                        });
                        return
                    }
                });
            }
     }
   }
</script>

登录后把token存在本地,这样哪个页面想用都可以直接取出来

  1. nvue和vue之间

也是通过定义全局事件来解决,例子参考第五点。

  1. app和H5之间

我用的uniapp 插件市场的一个插件
https://ext.dcloud.net.cn/plugin?id=1034
有想了解的可以查一下JSBridge的资料
https://juejin.im/post/5abca877f265da238155b6bc

好了,今天的分享就到这里了,觉得有帮助的就给作者点个赞吧,谢了,嘻嘻!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐