Vue2的组件通信

17 阅读1分钟

组件之间,相互传递数据 父传子

  • 主流(常用)---》 8种

    • 父组件把数据绑定在子组件标签属性上
    • 子组件通过props配置选项接收

子传父

  • 子组件通过 this.$emit()触发一个自定义事件,把数据传递出来
  • 父组件,通过 v-on (@)绑定自定义事件,然后再处理函数中,接收数据

bus中央事件总线

  • 在main.js入口文件, new一个空的vue实例对象,把这个属性对象,挂载在Vue的原型上,一般叫$bus
  • A组件通过 this.bus.bus.emit()触发一个自定义事件,把数据传递出去
  • B组件通过 this.bus.bus.on()绑定一个自定义事件, 在回调函数中,接收数据
<template>
    <div>
    <Son :sonProp="sonData" @customFn="getUser"></Son>
 </div>
</template>
import Son from "./son.vue"
export default {
    data(){
        return{
          sonData:"我是父传子的值",
           user:""
        }
    },
    components:{
      Son  
    },
    methods:{
        getUser(data){
            this.user=data
        }
    }
}
//----Son-------
<template>
  <div>
    <p>{{sonProp}}</p>
<button @click="goFatherData">点我子传父</button>
   </div>
</template>
export default {
    props:{
       sonProp:{
           type:"String",
           required:true,
           default:"我是父传子默认值"
       },
       data(){
           return{
            userInfo:"子传父的内容"   
           }
       },
        methods:{
            goFatherData(){
                this.$emit("customFn",this.userInfo)
            },
        }
    }
}

//------$bus中央处理事件-------
Vue.prototype.$bus=new Vue()//main.js中
<button @click="goBus">传递出去<button>
    goBus(){
   this.$bus.$emit("busFn",'bus传递出去的数据')
}
//B组件
msg:"",
 mounted(){
    this.$bus.$on('busFn',(data)=>{
        this.msg=data
    })
  },
//坑:两个组件都要同时渲染。

vuex

vuex是vue的状态管理仓库,主要解决1.多个组件共享数据的问题;2.组件传递数据层级过深的问题

5个核心

  • state:存放需要多个组件共享的数据 获取方式:this.$store.state
  • mutations:修改state的唯一方式(其实就是一个函数,触发就能修改state) 通过 this.$store.commit()修改状态 或 通过辅助函数 mapState修改状态
  • actions: 异步修改状态, 通过 this.$store.dispatc()触发, 或 通过辅助函数 mapActions 触发。actions最终还是需要commit一个mutation才能修改
  • getters: 获取方式:this.$store.getters 或 通过辅助函数 mapGetters 仓库中的计算属性,如果一个仓库的数据,多个地方需要使用,还要额外处理,那直接在getters处理就可以
  • modules:拆分仓库
const store=new Vuex.store({
    state:{},
    mutations:{},
    actions:{
        函数名(context){
            context.commit("mutation的函数名")
        }
    },
    getters:{}
})
#组件中操作:
export default{
    computed(){
        //取state
        ...mapState(["字段"])
        函数名(){//函数名就是字段对应的值
            return this.$store.state.字段
        }
        //取getters
        ...mapGetters(["字段"])
        函数名(){
            return this.$store.getters.字段
        }
    },
    methods:{
        //触发mutation
        ...mapMutation(["函数名"])
        函数名(){
    this.$store.commit("函数名")
}
//触发action
...mapAction(["函数名"])
函数名(){
    this.$store.dispatch("函数名")
}
    }
}
//坑:页面刷新,代码就会重新走,Vuex就会重新初始化。回到初始值。
解决方案:存本地~或者装插件vuex-persistedstate

组件传值

$attrs拿绑定到子组件标签上的属性(排除props接收了的和class,style)

$listeners拿绑定到子组件标签上的事件(排除:.native)

$parent拿到的是父组件的实例对象,可以获取到父组件上所有的东西

$children获取子组件实例(是个数组,因为可能多个子组件)

$refs可以拿到子组件的实例对象

$root拿到的是根组件实例(main.js里定义的数据)

provice提供和inject注入

provice选项应该是一个对象或返回一个对象的函数,可以提供数据

inject选项,是一个对象或数组,可以把祖辈组件,提供的数据,注入进入当前组件但数据不是响应式的

<dome ref="sonDome"></dome>
mounted(){
    this.$refs.sonDome
}