vuejs几种通信方式-

Vue的几种通信方式,今天这里做点笔记,源码使用的是非构建版的代码

1、父子组件之间通信

父组件通过props的方式向子组件传递数据

 <div id="app">
      {{msg}}
      <component-p :text="text"/>
    </div>
    const componentParent = {
        template:`<h2>我是组件A---{{text}}</h2>`,
        props:['text'],
        data(){
          return{
          }
        }
      }
      
      new Vue({
        el:"#app",
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        }
      })

2、子组件与父组件通信

通过$emit 子组件可以向父组件通信。

<div id="app">
      {{msg}}
      <component-p :text="text" @changedtext="changedtext2"/>
</div>

 

    const componentParent = {
        template:`<h2 @click='changedText'>我是组件A---{{text}}</h2>`,
        props:['text'],
        data(){
          return{
          }
        },
        methods:{
          changedText(){
            this.$emit('changedtext')
          }
        }
      }
    new Vue({
        el:"#app",
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        },
        methods:{
          changedtext2(){
            this.text = "我是被子组件修改了...."
          }
        }
      })

触发的时候还可以传递参数

    <div id="app">
      {{msg}}
      <component-p :text="text" @changedtext="changedtext2('参数测试22')"/>
    </div>

 

    const componentParent = {
        template:`<h2 @click='changedText'>我是组件A---{{text}}</h2>`,
        props:['text'],
        data(){
          return{
          }
        },
        methods:{
          changedText(value){
            this.$emit('changedtext',value)
          }
        }
      }

 

    new Vue({
        el:"#app",
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        },
        methods:{
          changedtext2(value){
            this.text = "我是被子组件修改了...."+value
          }
        }
      })

3、通过$parent$children就可以访问组件的实例

拿到实例代表什么?代表可以访问此组件的所有方法和data。接下来就是怎么实现拿到指定组件的实例。

子组件通过this.$parent.attr  直接到父组件的属性,通过计算属性,赋值给子组件

    <div id="app">
      {{msg}}
      <component-p />
    </div>
    const componentParent = {
        template:`<h2>我是组件A---{{text}}</h2>`,
        data(){
          return{
          }
        },
        computed: {
          text() {
            return this.$parent.text;
          }
        }
      }
    new Vue({
        el:"#app",
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        }
      })

 子组件触发父组件的事件:

    const componentParent = {
        template:`<h2 @click='clickHandle'>我是组件A---{{text}}</h2>`,
        data(){
          return{
          }
        },
        computed: {
          text() {
            return this.$parent.text;
          }
        },
        methods:{
          clickHandle(){
            this.$parent.showSomething();
          }
        }
      }

 

    new Vue({
        el:"#app",
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        },
        methods:{
          showSomething(){
            console.log('我是父组件的时间被触发啊')
          }
        }
      })

上面两种方式用于父子组件之间的通信, 而使用props进行父子组件通信更加普遍; 二者皆不能用于非父子组件之间的通信。

 

四、providereject  vue2.2.0 新增

具体的解释:https://cn.vuejs.org/v2/api/#provide-inject

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

 父组件provide一个对象,里面包含要让子组件接收的属性

    new Vue({
        el:"#app",
        provide:{
          slogon:'hello world'
        },
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        }
      })

 子组件注入相应的属性

    const componentParent = {
        template:`<h2>我是组件A---{{text}}</h2>`,
        inject:['slogon'],
        data(){
          return{
          }
        },
        computed:{
          text(){
            return this.slogon;
          }
        }
      }

以上是父子组件的,两个层级,现在我们再测试下父子孙的三层数据provide和eject

    const componentSon = {
        template:`<h2>我是组件Son---{{text}}</h2>`,
        inject:['slogon'],
        computed:{
          text(){
            return  this.slogon;
          }
        }
      }
    const componentParent = {
        template:`<div>
            <h2>我是组件A---{{text}}</h2>
            <component-s />
        </div>`,
        inject:['slogon'],
        data(){
          return{
          }
        },
        components:{
          'component-s': componentSon
        },
        computed:{
          text(){
            return this.slogon;
          }
        }
      }
     new Vue({
        el:"#app",
        provide:{
          slogon:'hello world'
        },
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        }
      })

尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,你可以通过 ref 特性为这个子组件赋予一个 ID 引用。

 

    <div id="app">
      {{msg}}
      <component-p  />
    </div>
    const componentParent = {
        template:`<h2 ref="compS"  @click="clickHanlde">我是组件A--</h2>`,
        data(){
          return{
            name:'我是父组件内的内容'
          }
        },
        methods:{
          clickHanlde(){
            console.log(123)
            console.log(this.$refs.compS)
            this.$refs.compS.style.background = "red"
          }
        }
      }
    new Vue({
        el:"#app",
        data:{
          msg:"这是一个app",
          text:"我是父组件的内容"
        },
        components:{
          'component-p':componentParent
        },
        methods:{
        }
      })

当ref挂在到子组件上是,获取到的就是子组件实例,因此可以拿到子组件的属性方法

  <div id="app">
    <component-a />
  </div>
var componnetB = {
    template: `<div><h2>我是组件B</h2></div>`,
    data() {
      return {
        name: 'hello world'
      }
    }
  }
  var componentA = {
    template: `<div><h2 @click="showSon">我是组件A</h2><component-b ref="comB"/></div>`,
    components: {
      'component-b': componnetB
    },
    methods: {
      showSon() {
        console.log('showSon')
        console.log(this.$refs.comB.name)
      }
    }
  }
  new Vue({
    el: "#app",
    data: {
      test: 'hello world'
    },
    components: {
      'component-a': componentA
    }
  })

 

 五、兄弟组件间的通信  bus

创建一个事件bus

参考地址https://cn.vuejs.org/v2/guide/migration.html#dispatch-%E5%92%8C-broadcast-%E6%9B%BF%E6%8D%A2

var bus = new Vue()

下面我们就来两个兄弟组件试试 

var componnetB = {
    template: `<div>
      <h2 >我是组件B</h2>
      {{count}}
      </div>`,
    data() {
      return {
        name: 'hello world_B',
        count: 0
      }
    },
    mounted() {
      //监听兄弟组件的触发,在组件被挂在的时候进行监听
      var self = this;
      eventHub.$on('add', function () {      //此处有个坑,要改变this指向
        console.log(222)
        self.count++;
      })

      /* eventHub.$on('add', () => {      //此处有个坑,要使用箭头函数
        console.log(222)
        this.count++;
      }) */
    },
    methods: {
      /* additionHandle() {
        this.data++;
      } */

    }
  }

var componnetC = {
    template: `<div><h2 @click="additionHandle">我是组件C</h2></div>`,
    data() {
      return {
        name: 'hello world_C'
      }
    },
    methods: {
      additionHandle() {
        eventHub.$emit('add')  //触发兄弟组件的事件
      }
    }
  }
  var componentA = {
    template: `<div>
      <h2 @click="showSon">我是组件A</h2>
      <component-b />
      <component-c />
      </div>`,
    components: {
      'component-b': componnetB,
      'component-c': componnetC
    },
    methods: {
      showSon() {
        console.log('showSon')
        console.log(this.$refs.comB.name)
      }
    }
  }
  new Vue({
    el: "#app",
    data: {
      test: 'hello world'
    },
    components: {
      'component-a': componentA
    }
  })

 移除事件监听

eventHub.$off('add', {})

6.vuex介绍此处略,会有专门的来记录这个 

7.localStorage / sessionStorage

这里是数据化的处理方式,不仔细说了,有相应的api,进行存取值

8.$attrs与 $listeners

https://cn.vuejs.org/v2/api/#vm-attrs

 

接下来我们实战,情景是A>>>>B>>>>C,父,子,孙的层级关系

  <div id="app">
    <component-a :name="name" :age="age" sex="中性a" color="golderna" />
  </div>

 总结一:子组件需要父组件的data,必须要一层一层的绑定v-bind='$attrs',组件D在组件C中使用的时候未进行绑定,打印出的是{}对象

总结二:color属性是通过props传递,默认的是不显示在$attrs中,

var componnetD = {
    template: `<div><h2>我是组件D</h2></div>`,
    data() {
      return {
        name: 'hello world_D'
      }
    },
    mounted() {
      console.log(this.$attrs, 'D')
    },
    inheritAttrs: false,
    methods: {}
  }

  var componnetC = {
    template: `<div>
      <h2>我是组件C</h2>
      <componnet-d />
      </div>`,
    data() {
      return {
        name: 'hello world_C'
      }
    },
    mounted() {
      console.log(this.$attrs, 'C')
    },
    inheritAttrs: false,
    components: {
      'componnet-d': componnetD
    },
    methods: {}
  }

  var componnetB = {
    template: `<div>
      <h2 >我是组件B</h2>
      <component-c v-bind="$attrs"/>
      </div>`,
    data() {
      return {
        name: 'hello world_B',
        count: 0
      }
    },
    mounted() {
      console.log(this.$attrs, 'B')
    },
    components: {
      'component-c': componnetC,
    }
  }
  var componentA = {
    template: `<div>
      <h2>我是组件A</h2>
      <p>{{$attrs}}</p>
      <component-b v-bind="$attrs"/>
      </div>`,
    props: ['color'],
    components: {
      'component-b': componnetB,
    },
    methods: {
    }
  }
  new Vue({
    el: "#app",
    data: {
      test: 'hello world',
      name: 'my name',
      age: '100'
    },
    components: {
      'component-a': componentA
    }
  })

参考的是文章:https://juejin.im/post/5d267dcdf265da1b957081a3

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值