没有废话的vue高级进阶( 二 ) 8种组件通信详解
栏目: JavaScript · 发布时间: 5年前
内容简介:vue组件通信的重要性无需多言。。。但是你肯定没有全部掌握,所以这第二篇文章应运而生props父传子,$emit子传父,看下边代码,清澈的像少女的眼眸。。。emmm新建一个Vue事件bus对象,然后通过
vue组件通信的重要性无需多言。。。但是你肯定没有全部掌握,所以这第二篇文章应运而生
props和$emit
props父传子,$emit子传父,看下边代码,清澈的像少女的眼眸。。。emmm
Vue.component('child',{ data(){ return { mymessage:this.message } }, template:` <div> <input type="text" v-model="mymessage" @input="passData(mymessage)"> </div> `, props:['message'],//得到父组件传递过来的数据 methods:{ passData(val){ //触发父组件中的事件 this.$emit('getChildData',val) } } }) ┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄* Vue.component('parent',{ template:` <div> <p>this is parent compoent!</p> <child :message="message" v-on:getChildData="getChildData"></child> </div> `, data(){ return { message:'张不怂' } }, methods:{ //执行子组件触发的事件 getChildData(val){ console.log(val) } } }) ┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄* // 挂载 var app=new Vue({ el:'#app', template:` <div> <parent></parent> </div> ` }) 复制代码
中央事件总线new Bus
新建一个Vue事件bus对象,然后通过 bus.$emit
触发事件, bus.$on
监听触发的事件。
Vue.component('brother1',{ data(){ return { mymessage:'hello brother1' } }, template:` <div> <p>this is brother1 compoent!</p> <input type="text" v-model="mymessage" @input="passData(mymessage)"> </div> `, methods:{ passData(val){ //触发全局事件globalEvent bus.$emit('globalEvent',val) } } }) ┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄* Vue.component('brother2',{ template:` <div> <p>this is brother2 compoent!</p> <p>brother1传递过来的数据:{{brothermessage}}</p> </div> `, data(){ return { mymessage:'hello brother2', brothermessage:'' } }, mounted(){ //绑定全局事件globalEvent bus.$on('globalEvent',(val)=>{ this.brothermessage=val; }) } }) ┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄* //中央事件总线 var bus=new Vue(); var app=new Vue({ el:'#app', template:` <div> <brother1></brother1> <brother2></brother2> </div> ` }) 复制代码
provide和inject
父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。
Vue.component('child',{ inject:['for'],//得到父组件传递过来的数据 data(){ return { mymessage:this.parent_var } }, template:` <div> {{ message }} </div> }) ┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄* Vue.component('parent',{ template:` <div> <child></child> </div> `, provide:{ parent_var:'test' }, data(){ return { message:'hello' } } }) ┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄* var app=new Vue({ el:'#app', template:` <div> <parent></parent> </div> ` }) 复制代码
$attrs
和$listeners
还是多层的场景,A-->B—>C,如果A直接想给C传递数据该怎么办? Vue 2.4 开始提供了 listeners来解决这个问题,能够让组件A之间传递数据给组件C。我将代码中关键点已经标注出, // ******关键点*****
A组件
<template> <div id="app"> {{app}} // ******关键点***** <A :app="app" @test="doTest"/> </div> </template> <script> import A from "./components/A"; export default { name: "App", data() { return { app: "我是App的数据" }; }, components: { A }, methods: { doTest() { console.log(this.app) } } }; 复制代码
B组件
<template> <div class="hello"> <h6>这里是A组件</h6> <p>$attrs: {{$attrs}}</p> <p>$listeners: {{$listeners}}</p> // ******关键点***** <B v-bind="$attrs" v-on="$listeners"/> </div> </template> <script> import B from "./B"; export default { name: "B", props: { msg: String }, components: { B }, mounted() { console.log(this.$listeners); } }; </script> 复制代码
C组件
<template> <div class="hello"> <h6>这里是B组件</h6> // ******关键点***** <p>$attrs: {{$attrs}}</p> </div> </template> <script> export default { name: "C", props: { msg: String }, mounted() { // ******关键点***** this.$emit("test"); } }; </script> 复制代码
$parent
和$children
分别是获得父组件和子组件的实例
Vue.component('child',{ props:{ value:String, //v-model会自动传递一个字段为value的prop属性 }, data(){ return { mymessage:this.value } }, methods:{ changeValue(){ this.$parent.message = this.mymessage;//通过如此调用可以改变父组件的值 } }, template:` <div> <input type="text" v-model="mymessage" @change="changeValue"> </div> }) Vue.component('parent',{ template:` <div> <p>this is parent compoent!</p> <button @click="changeChildValue">test</button > <child></child> </div> `, methods:{ changeChildValue(){ this.$children[0].mymessage = 'hello'; } }, data(){ return { message:'hello' } } }) var app=new Vue({ el:'#app', template:` <div> <parent></parent> </div> ` }) 复制代码
v-model
父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值
Vue.component('child',{ props:{ value:String, //v-model会自动传递一个字段为value的prop属性 }, data(){ return { mymessage:this.value } }, methods:{ changeValue(){ this.$emit('input',this.mymessage); //通过如此调用可以改变父组件上v-model绑定的值 } }, template:` <div> <input type="text" v-model="mymessage" @change="changeValue"> </div> }) Vue.component('parent',{ template:` <div> <p>this is parent compoent!</p> <p>{{message}}</p> <child v-model="message"></child> </div> `, data(){ return { message:'hello' } } }) var app=new Vue({ el:'#app', template:` <div> <parent></parent> </div> ` }) 复制代码
boradcast和dispatch
vue1.0中提供了这种方式,但vue2.0中没有,但很多开源软件都自己封装了这种方式,比如min ui、element ui, broadcast是向特定的父组件,触发事件,dispatch是向特定的子组件触发事件,本质上这种方式还是使用递归对on和emit的封装,但在一些基础组件中却很实用。注意:所有组件的名称不能重复!!!
function broadcast(componentName, eventName, params) { this.$children.forEach(child => { var name = child.$options.componentName; if (name === componentName) { child.$emit.apply(child, [eventName].concat(params)); } else { broadcast.apply(child, [componentName, eventName].concat(params)); } }); } function dispatch(componentName, eventName, params) { var parent = this.$parent; var name = parent.$options.componentName; while (parent && (!name && name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.componentName; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } } export default { methods: { dispatch(componentName, eventName, params) { dispatch.call(this, componentName, eventName, params); }, broadcast(componentName, eventName, params) { broadcast.call(this, componentName, eventName, params); } } }; 复制代码
vuex
对于vuex不再做过多的赘述。。。
第二章非常全面的讲解了vue炒鸡重要的一个技能,组件通信,我说这一篇全面大家应该没意见吧?好了就这样...
觉得对你有帮助,不妨点个
赞
,后续持续输出这种简短有效的文章,帮助你用最短的时间内掌握最多的内容,毕竟谁不喜欢一劳永逸不是? ❥(^_-) thank you ~
以上所述就是小编给大家介绍的《没有废话的vue高级进阶( 二 ) 8种组件通信详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 没有废话的vue进阶( 一 )
- 别废话,各种 SQL 到底加了什么锁?
- Python 函数式编程,没什么废话,直接看用法和代码
- 没有废话的vue高级进阶( 三 ) 组件高级用法及最佳实践
- Flutter 完整开发实战详解(十六、详解自定义布局实战)
- 数据结构 1 线性表详解 链表、 栈 、 队列 结合JAVA 详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。