51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

vue开发每日一学:分享组件通讯小秘诀

vue开发中,vue组件通讯经常会用到,今天我们来分享一些组件之间通信的一些常用方法,方便大家在项目中去应用,开始吧!!!

props 父组件--->子组件通信

父组件---属性的方式传值给子组件

子组件---props方式接收数据

<Son :datas="fData"></Son>

<script> import Son from '@/components/son'   export default{     name:'Father',     components:{Son},     data(){       return{         fData:'我是父组件向子组件传递的值-props方式'       }     }   } </script>

子组件props接受的参数名称,要与父组件传递时定义的属性名一致。

<template>
  <div>我是父组件的数据:{{fData}}</div>
  <div @click=changeData>我是父组件传递修改后的数据:{{mydata}}</div>
</template>
<script>
  export default{
    name:'Son',
    props:{
      fData:{
        type:String,
        default:''
      }
    }
    data(){
      mydata:this.fatherData
    },
    methods:{
     changeData(){
        this.mydata += '改变数据'
      }
    },
  }
</script>

注意:

  • 子组件不能够直接去修改父组件传递的值修改的:因为Vue的单向数据流机制,如果直接修改那父组件的值就被"污染"了。(props是单向绑定的(只读属性):当父组件的属性变化时,将传导给子组件,但是反过来不会)
    报错信息大概是:vue使用prop通信出错:Avoid mutating a prop directly since the value will be overwritten whenever the parent

  • 解决方案:可以在子组件内定义一个变量mydata去接收fData数据

  • 参数传递类型不确定是可以这么写:

props:{
    fData:{
        type:[String,Number],
        default:''
    }
}

$emit 子组件--->父组件传递

  • 子组件绑定自定义事件

  • $emit()第一个参数为:自定义的事件名称,第二个参数为:需要传递的数据

  • 使用 $emit() 触发更改数据

子组件

<el-button @click="handleEmit">改变父组件</el-button>

<script>  export default{    name:'Son',    methods:{      handleEmit(){        this.$emit('triggerEmit','子组件的数据')      }    }  } </script>

父组件(子组件发送的事件名称,要和父组件接受的事件名称一致)

<Son @triggerEmit="changeData"></Son>

<script>  import Son from '@/components/son'  export default{    name:'Father',    components:{Son},    methods:{      changeData(name){        console.log(name) // => 我是来自子组件的数据      }    }  } </script>

$emit与props结合 兄弟组件传值

  • 父组件引入两个子组件

  • 父组件充当一个桥梁作用

父组件

<childA :myName="name"></ChildA>
<ChildB :myName="name" @changeName="editName"></ChildB>  
    
export default{
  data() {
    return {
      name: '数据你好'
    }
  },
  methods: {
    editName(name){
      this.name = name
    }
  }
}

子组件B改变,接收数据

<p>姓名:{{ myName }}</p>

<button @click="changeName">修改姓名</button>
    
<script>
export default{
  props: {
    myName:String
  },
  methods: {
    changeName() {
      this.$emit('changeName', '新数据名称')
    }
}
}
</script>

子组件A接收数据。

<p>姓名:{{ newName }}</p>
    
<script>
export default{
  props: {
    myName:String
  }
}
</script>

bus(事件总线) 兄弟组件通信

非父子组件或更多层级间组件间传值,在Vue中通过单独的事件中心来管理组件间的传值

  1. 创建一个公共的bus.js文件

  2. 暴露出Vue实例

  3. 传递数据方,通过一个事件触发bus.$emit(方法名,传递的数据)

  4. 接收数据方,在生命周期函数中,通过bus.$on(方法名,[params])来监听

  5. 销毁事件,在接受数据方,通过bus.$off(方法名)销毁之后无法监听数据

import Vue from "vue"
const bus=new Vue()
export default bus

需要改变数据的组件中定义调用。

<template>
  <div>
    <div>我是通信组件A</div>
    <button @click="changeName">修改姓名</button>
  </div>
</template>

<script> import bus from "@/utils/Bus.js"; export default {   components: {},   data() {     return {};   },   mounted() {     console.log(bus);   },   methods: {     changeName() {       bus.$emit("editName", "数据集!");     },   }, }; </script>

<style scoped> </style>

另外一个组件中同样引入bus.js文件,通过$on监听事件回调。

<template>
  <div>
  <span>名称:{{name}}</span>
    <div>我是通信组件B</div>
  </div>
</template>

<script> import  bus  from "@/utils/Bus.js"; export default {   components: {},   data() {     return {name};   },   mounted() {     bus.$on("editName", (name) => {         this.name=name       console.log(name); //      });   },   methods: {}, }; </script>

<style scoped> </style>

$parent、$children 直接访问组件实例

  • 子组件通过---> $parent 获得父组件实例

  • 父组件通过---> $children 获得子组件实例数组

子组件---this.$parent可以获取到父组件的方法、data的数据等,并可以直接使用和执行

<template>
  <div>我是子组件</div>
</template>

<script> export default{   name:"Son",   data(){     return{       sonTitle: '我是子组件的数据'     }   },   methods:{     sonHandle(){       console.log('我是子组件的方法')     }   },   created(){     console.log(this.$parent)     console.log(this.$parent.fatherTitle) // => 我是父组件的数据     this.$parent.fantherHandle() // => 我是父组件的方法   } } </script>

父组件 --- 获取子组件实例的,并且获取的实例是一个数组形式,this.$children[0]才可以获取某个组件实例,并调用组件方法和数据。

<template>
  <div>
    <Son>我是父组件</Son>
  </div>
</template>

<script> import Son from './son.vue'

export default{   name: 'father',   components:{     Son   },   data(){     return{       fatherTitle: '我是父组件的数据'     }   },   methods:{     fantherHandle(){       console.log('我是父组件的方法')     }   },   mounted(){     console.log(this.$children)     console.log(this.$children[0].sonTitle) // => 我是子组件的数据     this.$children[0].sonHandle() // => 我是子组件的方法   } } </script>

$refs

ref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。

父组件使用 $refs 获得组件实例:

<template>
  <div>
    <Son ref="son"></Son>
  </div>
</template>

<script> import Son from './son.vue'

export default{   name: 'father',   components:{     Son   },   mounted(){     console.log(this.$refs.son) /组件实例/   } } </script>

provide/inject(提供/注入) 多组件或深层次组件通信

  • 父组件使用 provide 注入数据

  • 子组件使用 inject 使用数据

/*父组件*/
export default{
 provide: {
   return{
     provideName: '贩卖前端仔'
   }
 }
}

至此provideName这个变量可以提供给它其下的所有子组件,包括曾孙、孙子组件等,只需要使用 inject 就能获取数据。

/*子组件*/
export default{
  inject: ['provideName'],
  created () {
    console.log(this.provideName) // => "贩卖前端仔"
  }
}

slot(slot-scope作用域插槽) 子元素-->父元素(类似于通信)

  • 用作一个 (能被传递数据的)可重用模板,来代替已经渲染好的元素

  • 在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样

  • 注意:父级插槽接收内容是最外侧元素 ,必须要有属性slot-scope

子元素

<template>
  <div>
    <div class="isSon">
        <slot :info='arrList'></slot>
    </div>
  </div>
</template>

<script> export default {   components: {},   data() {     return {arrList:[1,'aa','张三']};   },   mounted() {   },   methods: {        }, }; </script>

父元素

<template>
<div>
    <SonG>
        <span slot-scope="props">
            <ul>
                aa
                <li v-for="item in props.info" :key="item">
                    {{item}}
                </li>
            </ul>
        </span>
    </SonG>
</div>
</template>

<script>

import SonG from '../components/SonG.vue' export default {    components:{        SonG    },    data () {        return {        }    } } </script>

vuex状态管理

相当于一个公共数据的仓库

提供一些方法管理仓库数据

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({   state: {   },   mutations: {   },   actions: {   },   modules: {   } })


赞(3)
未经允许不得转载:工具盒子 » vue开发每日一学:分享组件通讯小秘诀