我说这是全网最全vue组件通信方式,你没意见吧?

标题父子组件通信

    prop
    event
    style和class
    natvie修饰符
    $listeners
    v-model
    sync修饰符
    $parent和$children
    $slots和$scopedSlots
    ref    

跨组件通信

    Provide和Inject
    router
    vuex
    store模式
    eventbus

父子组件通信


prop


最常见的组件通信方式,由父组件向子组件传递。prop可接收一个数组或对象

//子组件
<script>
export default {
  name: "Comp",
  //数组方式 props:[....]
  // ↓ 对象方式
  props: {
    datas: {
      type: Object,
      default: () => {
        return {};
      }
     },
  }
</script>


 event 


子组件向父组件发送通知,并传递参数

子组件

methods:{
    // 通过 $emit向父组件发送一个通知
    handleEvent(){
      this.$emit('eventMsg', option)
    }
  }


父组件

methods:{
    // 监听子组件定义的方法
    eventMsg(option){
      console.log(option);
    }
  }

  
 style 和 class 


父组件可以向子组件传递style 和 class ,style 和 class将合并到子组件根元素上

父组件

<template>
  <div id="app">
    <HelloWorld
      style="color:red"
      class="hello"
      msg="Welcome to Your Vue.js App"
    />
  </div>
</template>
​
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
  components: {
    HelloWorld,
  },
};
</script>


子组件​

<template>
  <div class="world" style="text-align:center">
    <h1>{{msg}}</h1>
  </div>
</template>
​
<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
};
</script>


最终渲染结果

<div id="app">
  <div class="hello world" style="color:red; text-aling:center">
    <h1>Welcome to Your Vue.js App</h1>
  </div>
</div>


 attribute 


父组件在使用子组件时,在子组件上定义一些属性,这些属性将作用于子组件的根元素上,但是不包括style和class

父组件


<HelloWorld data-a="1" data-b="2" msg="Welcome to Your Vue.js App" />


子组件


<template>
  <div>
    <h1>{{msg}}</h1>
  </div>
</template>
​
<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  created() {
    // 通过$attrs获取父组件定义的 attribute
    console.log(this.$attrs); // {"data-a":"1","data-b":"2"}
  },
};
</script>


最终渲染结果 

<div id="app">
  <div data-a="1" data-b="2">
    <h1>Welcome to Your Vue.js App</h1>
  </div>
</div>

Tip:子组件可以通过定义 inheritAttrs:false 来紧张 attribute 附着在子组件根元素上 但不影响通过  $attrs 获取数据  

natvie修饰符 


在注册事件时,父组件可以通过 navite 修饰符,将事件注册到子组件根元素上

父组件


<template>
  <div id="app">
    <HelloWorld @click.native="handleClick" />
  </div>
</template>
​
<script>
import HelloWorld from "./components/HelloWorld.vue";
​
export default {
  components: {
    HelloWorld,
  },
  methods: {
    handleClick() {
      console.log(1);
    },
  },
};
</script>


子组件


<template>
  <div>
    <h1>Hello World</h1>
  </div>
</template>


最终渲染结果


<template>
  <div id="app">
    <h1>Hello World</h1>
  </div>
</template>
// 当点击app时。会触发父组件定义的 handleClick 方法


 $listeners 


子组件可以通过 $listeners  获取父组件传递过来的所有处理函数

 v-model 


父组件在使用子组件时,可以在子组件上绑定v-model,子组件通过定义model的prop和event还获取父组件定义的值

父组件​


<Compn v-model="datas" />

子组件


<script>
export default {
  //分类筛选组件
  name: "sortFilter",
  //定义实现v-modal的属性与事件
  model: {
    prop: "value",
    event: "change"
  },
  props: {
    //绑定的值
    value: {
      type: [String, Number],
      default: ""
    }
   },
   created() {
    console.log(this.value)
  },
    
</script>


sync 修饰符 


和 v-model类似,用于双向数据绑定,不同点在于 v-model只能针对一个数据进行绑定,而 sync 修饰符没有限制

子组件​


<template>
  <div>
    <p>
      <button @click="$emit(`update:num1`, num1 - 1)">-</button>
      {{ num1 }}
      <button @click="$emit(`update:num1`, num1 + 1)">+</button>
    </p>
    <p>
      <button @click="$emit(`update:num2`, num2 - 1)">-</button>
      {{ num2 }}
      <button @click="$emit(`update:num2`, num2 + 1)">+</button>
    </p>
  </div>
</template>
​
<script>
export default {
  props: ["num1", "num2"],
};
</script>

父组件​


<template>
  <div id="app">
    <Numbers :num1.sync="n1" :num2.sync="n2" />
    <!-- 等同于 -->
    <Numbers
      :num1="n1"
      @update:num1="n1 = $event"
      :num2="n2"
      @update:num2="n2 = $event"
    />
  </div>
</template>
​
<script>
import Numbers from "./components/Numbers.vue";
​
export default {
  components: {
    Numbers,
  },
  data() {
    return {
      n1: 0,
      n2: 0,
    };
  },
};
</script>


 $parent 和 $children 


在组件内部,可以通过$parent 和$children属性,分别获取当前组件的父组件和子组件实例


<template>
  <div class="hello">
    <button @click="handelParent">获取父组件实例</button>
    <button @click="handelChild">获取子组件实例</button>
    <Child />
  </div>
</template>
​
<script>
import Child from "./Children.vue";
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  components: {
    Child,
  },
  methods: {
    handelParent() {
      console.log("父组件实例:", this.$parent);
    },
    handelChild() {
      console.log("子组件实例", this.$children);
    },
  },
};
</script>

ref 


在使用组件时,可以通过在组件上定义ref来获取组件实例


<template>
  <div class="hello">
    <button @click="handelChild">获取子组件实例</button>
    <Child ref="child" />
  </div>
</template>
​
<script>
import Child from "./Children.vue";
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  components: {
    Child,
  },
  methods: {
    handelChild() {
      console.log("子组件实例", this.$refs.child);
    },
  },
};
</script>


跨组件通信


 provide 和 Inject 


provide和inject 可以实现深层组件通信,顶层组件只需定义provide,底层组件通过inject接受数据

如图

顶层组件



// 父组件
provide(){
  msg:'hello Children'
},
​
// 子组件
inject: ['msg']
created () {
  console.log(this.msg) // hello Children
}
​


 router 


如果一个组将改变了地址栏,所有监听地址栏的组将都会做出相应的改变,


//监听路由变化
watch:{
    $route(to,from) {
      console.log(to,from);
    }
}


 vuex 


vuex 过于笨重,通常不建议在小型项目中使用,小型项目可以使用store 或 eventbus代替vuex,vuex本质上就是一个数据仓库。在此不做过多赘述,先挖一个坑,下回再叙。

 store 模式 


store模式其实就是一个普通的js模块,各组件可以导入该模块,将数据放到data里面,此时store就具有响应式了。


// 导出一个 store.js模块
export default {
    userInfo:{...},
    loginInfo:{...}
}
​
​
// A子组件导入 store模块
import store from './store.js'
export default {
  name:'Acompon',
  data(){
    userInfo: store.userInfo
  }
}
​
// B子组件导入 store模块
import store from './store.js'
export default {
  name:'Bcompon',
  data(){
    loginInfo: store.loginInfo
  }
}





tip: store模式的缺点是无法跟踪数据的改变,因为所有组件都可以更改数据   

 eventbus 


eventbus事件总线相当于一个桥梁,作为所有组将的一个事件中心,所有组件皆可往eventbus里面注册事件,也可以监听事件。


// 定义一个eventbus模块
import Vue from 'vue'
export const EventBus = new Vue()
​


在main.js里导入该模块并挂载到全局


// main.js
import eventbus from './eventbus.js'
​
Vue.prototype.$eventBus = eventbus
​


所有子组件向eventbus里组 注册 或者 监听 事件


// 组件A 通过 $emit()注册事件
sendMsg() {
   this.$eventBus.$emit("aMsg", 'from A');
}
​
// 组件B 通过 $on 监听事件
this.$eventBus.$on("aMsg", (msg) => {
    // A发送来的消息
    console.log(msg) // from A
})
​
// 通过 $off() 可以关闭事件



 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值