Vue组件之间的通信

        vue组件实例的作用域是相互独立的,不同组件之间的数据无法相互引用。要想跨组件引用数据,需要用到组件通信

        组件通信分为

        1.父与子之间的通信

        2.非父与子之间的通信(兄弟、隔代、跨级)


方式一:props/$emit

        父和子之间


1.父组件向子组件传递数据props

        

        父组件:

//App.vue
<template>
  <Child v-for="list in lists" 
  :title="list.name"
  :price="list.price"
  :info="list.info"
  ></Child>
</template>
<script>
import Child from "./components/Child.vue"
export default{
  components:{
    Child
  },
  data(){
    return{
      lists:[{name:"css",price:18,info:"学习"}]
    }
  }
}
</script>

        子组件:

//Child.vue
<template>
    <div class="box">
        <h3>书籍:{{title}}</h3>
        <p>价格:{{price}}</p>
        <p>{{info}}</p>
    </div>
</template>
<script>
export default{
    props:['title','price','info']
}
</script>
<style>
.box{
    border: 1px solid #ccc;
}
</style>

 2.子组件向父组件传递数据$emit

        父组件:@自定义事件名="在父组件中定义的函数"

        

//App.vue
<template>
  <Child v-for="list in lists" 
  :title="list.name"
  :price="list.price"
  :info="list.info"
  @showMessage="mes"
  ></Child>
</template>
<script>
import Child from "./components/Child.vue"
export default{
  components:{
    Child
  },
  data(){
    return{
      lists:[{name:"css",price:18,info:"学习"}]
    }
  },
  methods:{
    mes(){
      alert("你查看了数据")
    }
  }
}
</script>

        父组件:

//Child.vue
<template>
    <div class="box">
        <h3>书籍:{{title}}</h3>
        <p>价格:{{price}}</p>
        <p>{{info}}</p>
        <button @click="show">按钮</button>
    </div>
</template>
<script>
export default{
    props:['title','price','info'],
    methods:{
        show(){
            this.$emit('showMessage')
        }
    }
}
</script>
<style>
.box{
    border: 1px solid #ccc;
}
</style>

方式二:$parent/$children

        父和子之间

 $parent:访问父组件实例

 $children:访问子组件实例

父组件:

//App.vue
<template>
  <span>{{msg}}</span>
  <Child></Child>
</template>
<script>
import Child from "./components/Child.vue"
export default{
  data(){
    return{
      msg:"father"
    }
  },
  components:{
    Child
  },
}
</script>

 子组件

//Child.vue
<template>
    <p>{{messageA}}</p>
    <p>父组件值为:{{fatherMes}}</p>
</template>
<script>

export default{
    data(){
        return{ 
        messageA:"son"
        }
    },
    computed:{
        fatherMes(){
            return this.$parent.msg
        }
    }
}
</script>

方法三:ref/refs

        父调子

如果在普通的DOM元素上使用,引用指向的就是DOM元素,如果用在子组件上,引用就是指向组件实例,可以通过实例直接调用组件的方法或访问数据

 

父组件:

//App.vue
<template>
  <Child ref="son"></Child>
</template>
<script>
import Child from './components/Child.vue'
  export default {
    components:{
      Child 
   },
    mounted () {
      const show= this.$refs['son'].msg;
      console.log(show);  
      this.$refs['son'].sayHello();
      console.log("--------")
      const show2=this.$refs.son;
      console.log(show2.msg);
      show2.sayHello();
    }
  }
</script>

子组件:

//Child.vue
<template>

</template>
<script>
export default{
    data(){
        return{
            msg:"son"
        }
    },
    methods:{
        sayHello(){
            console.log('hello')
        }
    }
}
</script>

 方法四:provide/inject

        跨级

父组件通过provide提供变量,子子孙孙组件通过inject来注入变量

父组件:

//App.vue
<template>
  <Child></Child>
</template>
<script>
import Child from "./components/Child.vue"
export default{
  components:{
    Child
  },
  provide:{
    msg:"fatherMessage"
  }
}
</script>

子组件:

//Child.vue
<template>
    <div class="son">
        <div>子</div>
        {{message}}
        <grandChild></grandChild>
    </div>
</template>
<script>
import grandChild from "./grandChild.vue"
export default{
    components:{
        grandChild
    },
    inject:['msg'],
    data(){
        return{
            message:this.msg
        }
    }
}
</script>
<style>
.son{
    border: 1px solid black;
    background-color: greenyellow;
}
</style>

孙组件:

//grandChild.vue
<template>
    <div class="grandson">
        <div>孙</div>
        {{message}}
    </div>
</template>
<script>
export default{
    inject:['msg'],
    data(){
        return{
            message:this.msg
        }
    }
}
</script>
<style>
.grandson{
    color: black;
    border: 1px solid black;
    background-color: pink;
    margin-left: 15px;
}
</style>

 方法五:eventBus

        任意组件之间

1.实例化,在全局引入

//main.js
import Vue from 'vue'
export const EventBus=new Vue()

方法六:$attrs/$listeners

        跨级之间

$attrs包含了父组件中不作为prop被识别(且获取)的attribute绑定(class和style除外);子组件还可以使用v-bind="$attrs"的形式将所有父组件传来的数据(除开已经props声明了的)传向下一级子组件,通常和interitAttrs属性一起使用

 父组件:

//App.vue
<template>
  <ChildA 
    :A="A"
    :B="B"
    :C="C"
    :D="D"
  ></ChildA>
</template>
<script>
import ChildA from "./components/ChildA.vue"
export default{
  components:{
    ChildA
  },
  data(){
    return{
      A:"A",
      B:"B",
      C:"C",
      D:"D"
    }
  }
}
</script>

子组件:

//ChildA.vue
<template>
  <div class="childA">
    ----------------------------
    <h3>直接使用$attrs</h3>
    ----------------------------
    <p>A:{{ A }}</p>
    <P>App传递到A的数据:{{ $attrs }}</P>
    <ChildB v-bind="$attrs"></ChildB>
  </div>
</template>
<script>
import ChildB from "./ChildB.vue"
export default {
  components:{
    ChildB
  },
  inheritAttrs: false, //关闭自动挂载到组件根元素上的没有在props声明的属性
  props: {
    A: {},
  },
  created() {
    console.log(this.$attrs);
  },
};
</script>
<style>
.childA{
    background-color: greenyellow;
    padding: 10px;
}
</style>

孙组件:

//ChildB.vue
<template>
    <div class="childB">
        ----------------------------
        <h3>使用v-bind="$attrs"</h3>
        ----------------------------
        <p>B:{{B}}</p>
        <p>App传递到A再传递到B的数据:{{$attrs}}</p>
    </div>
</template>
<script>
export default{
    inheritAttrs:false,
    props:{
        B:{}
    },
    created(){
        console.log(this.$attrs)
    }
}
</script>
<style>
.childB{
    background-color: pink;
    margin-left: 15px;
    padding: 10px;
}
</style>

’$listeners包含父组件中的(不含.native修饰器的)v-on事件监听器。可以通过v-on="$listeners"传入内部组件

方法七:localStorage/sessionStorage

        任意组件

localStorage:本地存储对象,存储的数据是永久性数据,页面刷新,即使浏览器重启,除非主动删除不然存储的数据会一直存在
sessionStorage:与localStorage相似,但是只有在当前页面下有效,关闭页面或浏览器存储的数据将会清空

setItem(key,value)

getItem(key)

removeItem(key) 删除单个数值,根据键值移除对应的信息

clear() 删除所有数据

key(index) 获取某个索引的key

方法八:Vuex

        任意组件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值