精华内容
下载资源
问答
  • vuejs组件通信

    2019-04-22 17:00:29
    组件通信 所有的组件通信都是单向的 父子组件通信 A:邦定的是简单数据类型 1、父组件中定义数据,通过单向数据绑定属性把父组件的数据绑定在子组件身上,属性是自定属性 2、子属性通过配置项中的props接收数据,...

    组件通信

    所有的组件通信都是单向的

    父子组件通信

    A:邦定的是简单数据类型
    1、父组件中定义数据,通过单向数据绑定属性把父组件的数据绑定在子组件身上,属性是自定属性
    2、子属性通过配置项中的props接收数据,props可以是一个数组,数组中放的是自定义属性
    3、这个自定义属性可以像data的属性一样直接使用
    4、父组件中数据一旦修改,子组件中的通信数据也会改变(单向数据邦定)

            <Father></Father>
        </div>
        <template id="father">
            <div class="father-box">
                <h3>father 组件</h3>
                <p>{{money}}</p>
                <hr>
                <Son :money="money"></Son>
            </div>
        </template>
        <template id="son">
            <div class="son-box">
                <h3>son组件</h3>
                、<input type="text" v-model='money'> 如果money不是引用数据类型就会出错
                <p>这是我爸这个月给我的生活费:{{money}}</p>
            </div>
        </template>
        <script>
            Vue.component('Father', {
                template: '#father',
                data() {
                    return {
                        money: 1000
                    }
                }
            })
            Vue.component('Son', {
                template: '#son',
                props: ['money']
            })
            new Vue({
                el: '#app'
            })
        </script>
    
        
     #### 子父通信(效果上像,间接的使用了父组件的东西)   
    B:邦定复杂数据类型--------【不推荐】
        1、父组件中的数据类型是复杂数据类型,那么父组件邦定数据的时候,给子组件的是一个引用地址,
        2、子组件可以通过这个引用地址,改修了这个数据
        3、效果上,子组件和父组件通信了,违背单向数据流
    
    html代码
    html
    <div id="app">
            <Father></Father>
        </div>
        <template id="father">
            <div>
                <h3>father 组件</h3>
                <p>私房钱{{money.moneys}}</p>
                <hr>
                <Son :money='money'></Son>
            </div>
        </template>
        <template id="son">
            <div>
                <h3>son 组件</h3>
                <input type="text" v-model='money.moneys'>
                <p>这是我爸这个月给我的生活费{{money.moneys}}</p>
            </div>
        </template>
        ```
        js代码
        ```js
        <script>
            Vue.component('Father', {
                template: '#father',
                data() {
                    return {
                        money: {
                            moneys: 1000
                        }
                    }
                }
            })
            Vue.component('Son', {
                template: '#son',
                props: ['money']
            })
            new Vue({
                el: '#app'
            })
        </script>
    

    C:父组件可以传递一个方法给子组件
    1、父组件定义方法,然后将这个方法通过单向数据绑定的形式传递给子组件
    2、子组件通过props属性接收,然后通过@click = ‘方法名’
    html:

    <div id="app">
            <King></King>
        </div>
        <template id="king">
            <div>
                    <h3>king 组件</h3>
                    <p>{{money}}</p>
                    <hr>
                    <Pingming :getmoney='getMoney'>    </Pingming>
            </div>
        </template>
        <template id="pingming">
           <div>
                <h3>pingming 组件</h3>
                <input type="button" @click='getmoney(1000)' value="上缴">
           </div>
        </template>
    

    js:

     <script>
            Vue.component('King', {
                template: '#king',
                data() {
                    return {
                        money: 0
                    }
                },
                methods: {
                    getMoney(value) {
                        this.money += value
                    }
                }
            })
            Vue.component('Pingming', {
                template: '#pingming',
                props: ['getmoney']
            })
            new Vue({
                el: '#app'
            })
        </script>
    

    D:通过自定义事件来实现通信
    1、在父组件中定义 数据 和 方法 (方法是用来操作数据的)
    2、在子组件身上绑定自定义事件
    3、子组件定义方法,在这个方法中通过 this.$emit(eventType,实际参数) 来调用自定义事件处理程序
    html代码

    
    <div id="app">
    <King></King>
    </div>
    <template id="king">
    <div>
    <p>King 组件</p>
    <p>{{money}}</p>
    <People @get="get"></People>
    </div>
    </template>
    <template id="people">
    <div>
    <p>people组件</p>
    <p>{{moneys}}</p>
    <input type="button" value="上缴" @click='give'>
    </div>
    </template>
    
    
    

    js代码

    
          Vue.component('King', {
              template: '#king',
              data() {
                  return {
                       money: 0
                  }
              },
              methods: {
                  get(value) {
                      this.money += value
              }
            }
              })
            Vue.component('People', {
            template: '#people',
            data() {
              return {
                  moneys: 1000
              }
            },
            methods: {
              give() {
                  this.$emit('get', this.moneys)
              }
           }
        })
    
    
    

    非父子组件通信

    -使用ref来绑定组件,(注意:ref也可以绑定DOM元素)(ref链)
        1、在父组件的模板中,使用ref = ‘name’绑定在两个兄弟组件身上,
        2、在任意一个子组件中,就可以通过 this.$parent.$ref.refName 就可以获得另一个子组件了,同时这个子组件身上的数据和方法同样也得到 了
        
    -通过事件总线(bus)(没有共同的父组件----根组件不算(new 实例))
    1、它是通过事件的发布,以及事件的订阅(触发)来做的
    2、首先在js中,创建一个bus对象(vm)
        ````javascript
            var bus = new Vue()
        ```
    3、在count组件中定义数据,和修改数据的方法
    4、在count组件中 通过created钩子,进行bus事件的发布
        ```javascript
            created:{
                bus.$on('add',this.addCount)
            }
    
        5、在MyButton组件的方法中通过bus进行事件的订阅
        ```javascript
            increment(){
                bus.$emit('add')
            }
    
    展开全文
  • 组件的分类 常规页面组件,由 vue-router 产生的每个页面,它本质上也是一个组件(.vue),主要承载当前页面的 HTML 结构,会包含数据获取、数据整理、数据可视化等常规业务。 功能性抽象组件,不包含业务,独立、...

    组件的分类

    1. 常规页面组件,由 vue-router 产生的每个页面,它本质上也是一个组件(.vue),主要承载当前页面的 HTML
      结构,会包含数据获取、数据整理、数据可视化等常规业务。
    2. 功能性抽象组件,不包含业务,独立、具体功能的基础组件,比如日期选择器、弹窗警告等。这类组件作为项目的基础控件,会被大量使用,因此组件的
      API 进行过高强度的抽象,可以通过不同配置实现不同的功能。
    3. 业务组件,它不像第二类独立组件只包含某个功能,而是在业务中被多个页面复用的,它与独立组件的区别是,业务组件只在当前项目中会用到,不具有通用性,而且会包含一些业务,比如数据请求;而独立组件不含业务,在任何项目中都可以使用,功能单一,比如一个具有数据校验功能的输入框。

    组件的关系

    父子组件

    父子关系即是组件 A 在它的模板中使用了组件 B,那么组件 A 就是父组件,组件 B 就是子组件。

    // 注册一个子组件
    Vue.component('child', {
        data: function(){
            return {
                text: '我是father的子组件!'
            }
        },
        template: '<span>{{ text }}</span>'
    })
    // 注册一个父组件
    Vue.component('father', {
        template: '<div><child></child></div>'  // 在模板中使用了child组件
    })
    

    兄弟组件
    两个组件互不引用,则为兄弟组件。

    Vue.component('brother1', {
        template: '<div>我是大哥</div>'
    })
    Vue.component('brother2', {
        template: '<div>我是小弟</div>'
    })
    

    使用组件的时候:

    <div id="app">
        <brother1></brother1>
        <brother2></brother2>
    </div>
    

    跨级组件
    就是在父子关系中,中间跨了很多个层级

    组件的构成

    一个再复杂的组件,都是由三部分组成的:prop、event、slot,它们构成了 Vue.js 组件的 API。

    属性 prop
    prop 定义了这个组件有哪些可配置的属性,组件的核心功能也都是它来确定的。写通用组件时,props 最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,这点在组件开发中很重要,然而很多人却忽视,直接使用 props 的数组用法,这样的组件往往是不严谨的。

    插槽 slot
    插槽 slot,它可以分发组件的内容。和 HTML 元素一样,我们经常需要向一个组件传递内容,像这样:

    <alert-box>
      Something bad happened.
    </alert-box>
    

    可能会渲染出这样的东西:

    Error!Something bad happended.
    

    幸好,Vue 自定义的 元素让这变得非常简单:

    Vue.component('alert-box', {
      template: `
        <div class="demo-alert-box">
          <strong>Error!</strong>
          <slot></slot>
        </div>
      `
    })
    

    如你所见,我们只要在需要的地方加入插槽就行了——就这么简单!

    自定义事件 event

    两种写法:

    • 在组件内部自定义事件event
    <template>
      <button @click="handleClick">
        <slot></slot>
      </button>
    </template>
    <script>
      export default {
        methods: {
          handleClick (event) {
            this.$emit('on-click', event);
          }
        }
      }
    </script>
    

    通过 $emit,就可以触发自定义的事件 on-click ,在父级通过 @on-click 来监听:

    <i-button @on-click="handleClick"></i-button>
    
    • 用事件修饰符 .native直接在父级声明
      所以上面的示例也可以这样写:
    <i-button @click.native="handleClick"></i-button>
    

    如果不写 .native 修饰符,那上面的 @click 就是自定义事件 click,而非原生事件 click,但我们在组件内只触发了 on-click 事件,而不是 click,所以直接写 @click 会监听不到。

    组件的通信

    ref和 p a r e n t 和 parent和 parentchildren
    Vue.js 内置的通信手段一般有两种:

    • ref:给元素或组件注册引用信息;
    • $parent / $children:访问父 / 子实例。

    用 ref 来访问组件(部分代码省略):

    // component-a
    export default {
      data () {
        return {
          title: 'Vue.js'
        }
      },
      methods: {
        sayHello () {
          window.alert('Hello');
        }
      }
    }
    
    <template>
      <component-a ref="comA"></component-a>
    </template>
    <script>
      export default {
        mounted () {
          const comA = this.$refs.comA;
          console.log(comA.title);  // Vue.js
          comA.sayHello();  // 弹窗
        }
      }
    </script>
    

    $parent 和 $children 类似,也是基于当前上下文访问父组件或全部子组件的。
    这两种方法的弊端是,无法在跨级或兄弟间通信,比如下面的结构:

    // parent.vue
    <component-a></component-a>
    <component-b></component-b>
    <component-b></component-b>
    

    我们想在 component-a 中,访问到引用它的页面中(这里就是 parent.vue)的两个 component-b 组件,那这种情况下,是暂时无法实现的,后面会讲解到方法。

    provide / inject

    一种无依赖的组件通信方法:Vue.js 内置的 provide / inject 接口

    provide / inject 是 Vue.js 2.2.0 版本后新增的 API,在文档中这样介绍 :
    这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。
    provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
    假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件:

    // A.vue
    export default {
      provide: {
        name: 'Aresn'
      }
    }
    
    // B.vue
    export default {
      inject: ['name'],
      mounted () {
        console.log(this.name);  // Aresn
      }
    }
    

    需要注意的是:
    provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

    只要一个组件使用了 provide 向下提供数据,那其下所有的子组件都可以通过 inject 来注入,不管中间隔了多少代,而且可以注入多个来自不同父级提供的数据。需要注意的是,一旦注入了某个数据,那这个组件中就不能再声明 这个数据了,因为它已经被父级占有。

    provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。然后有两种场景它不能很好的解决:

    • 父组件向子组件(支持跨级)传递数据;
    • 子组件向父组件(支持跨级)传递数据。

    这种父子(含跨级)传递数据的通信方式,Vue.js 并没有提供原生的 API 来支持,下面介绍一种在父子组件间通信的方法 dispatch 和 broadcast。

    ** $ attrs和 $ listeners **
    如果父组件A下面有子组件B,组件B下面有组件C,这时如果组件A想传递数据给组件C怎么办呢? Vue 2.4开始提供了 $ attrs和$ listeners来解决这个问题,能够让组件A之间传递消息给组件C。

    Vue.component('C',{
            template:`
                <div>
                    <input type="text" v-model="$attrs.messagec" @input="passCData($attrs.messagec)"> </div>
            `,
    
            methods:{
                passCData(val){
                    //触发父组件A中的事件
                    this.$emit('getCData',val)
                }
            }
        })
    
        Vue.component('B',{
            data(){
                return {
                    mymessage:this.message
                }
            },
            template:`
                <div>
                    <input type="text" v-model="mymessage" @input="passData(mymessage)"> 
                    <!-- C组件中能直接触发getCData的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
                    <!-- 通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
                    <C v-bind="$attrs" v-on="$listeners"></C>
                </div>
            `,
            props:['message'],//得到父组件传递过来的数据
            methods:{
                passData(val){
                    //触发父组件中的事件
                    this.$emit('getChildData',val)
                }
            }
        })
        Vue.component('A',{
            template:`
                <div>
                    <p>this is parent compoent!</p>
                    <B :messagec="messagec" :message="message" v-on:getCData="getCData" v-on:getChildData="getChildData(message)"></B>
                </div>
            `,
            data(){
                return {
                    message:'hello',
                    messagec:'hello c' //传递给c组件的数据
                }
            },
            methods:{
                getChildData(val){
                    console.log('这是来自B组件的数据')
                },
                //执行C子组件触发的事件
                getCData(val){
                    console.log("这是来自C组件的数据:"+val)
                }
            }
        })
        var app=new Vue({
            el:'#app',
            template:`
                <div>
                    <A></A>
                </div>
            `
        })
    

    派发与广播——自行实现 dispatch 和 broadcast 方法

    要实现的 dispatch 和 broadcast 方法,将具有以下功能:
    在子组件调用 dispatch 方法,向上级指定的组件实例(最近的)上触发自定义事件,并传递数据,且该上级组件已预先通过 $on 监听了这个事件;
    相反,在父组件调用 broadcast 方法,向下级指定的组件实例(最近的)上触发自定义事件,并传递数据,且该下级组件已预先通过 $on 监听了这个事件。

    // 部分代码省略
    import Emitter from '../mixins/emitter.js'
    
    export default {
      mixins: [ Emitter ],
      methods: {
        handleDispatch () {
          this.dispatch();  // ①
        },
        handleBroadcast () {
          this.broadcast();  // ②
        }
      }
    }
    
     //emitter.js 的代码:
    function broadcast(componentName, eventName, params) {
      this.$children.forEach(child => {
        const name = child.$options.name;
    
        if (name === componentName) {
          child.$emit.apply(child, [eventName].concat(params));
        } else {
          broadcast.apply(child, [componentName, eventName].concat([params]));
        }
      });
    }
    export default {
      methods: {
        dispatch(componentName, eventName, params) {
          let parent = this.$parent || this.$root;
          let name = parent.$options.name;
    
          while (parent && (!name || name !== componentName)) {
            parent = parent.$parent;
    
            if (parent) {
              name = parent.$options.name;
            }
          }
          if (parent) {
            parent.$emit.apply(parent, [eventName].concat(params));
          }
        },
        broadcast(componentName, eventName, params) {
          broadcast.call(this, componentName, eventName, params);
        }
      }
    };
    

    因为是用作 mixins 导入,所以在 methods 里定义的 dispatch 和 broadcast 方法会被混合到组件里,自然就可以用 this.dispatch 和 this.broadcast 来使用。
    这两个方法都接收了三个参数,第一个是组件的 name 值,用于向上或向下递归遍历来寻找对应的组件,第二个和第三个就是上文分析的自定义事件名称和要传递的数据。
    可以看到,在 dispatch 里,通过 while 语句,不断向上遍历更新当前组件(即上下文为当前调用该方法的组件)的父组件实例(变量 parent 即为父组件实例),直到匹配到定义的 componentName 与某个上级组件的 name 选项一致时,结束循环,并在找到的组件实例上,调用 $emit 方法来触发自定义事件 eventName。broadcast 方法与之类似,只不过是向下遍历寻找。

    来看一下具体的使用方法。有 A.vue 和 B.vue 两个组件,其中 B 是 A 的子组件,中间可能跨多级,在 A 中向 B 通信:

    <!-- A.vue -->
    <template>
        <button @click="handleClick">触发事件</button>
    </template>
    <script>
      import Emitter from '../mixins/emitter.js';
      
      export default {
        name: 'componentA',
        mixins: [ Emitter ],
        methods: {
          handleClick () {
            this.broadcast('componentB', 'on-message', 'Hello Vue.js');
          }
        }
      }
    </script>
    
    // B.vue
    export default {
      name: 'componentB',
      created () {
        this.$on('on-message', this.showMessage);
      },
      methods: {
        showMessage (text) {
          window.alert(text);
        }
      }
    }
    

    同理,如果是 B 向 A 通信,在 B 中调用 dispatch 方法,在 A 中使用 $on 监听事件即可。
    以上就是自行实现的 dispatch 和 broadcast 方法。

    找到任意组件实例——findComponents 系列方法

    它适用于以下场景:

    由一个组件,向上找到最近的指定组件;
    由一个组件,向上找到所有的指定组件;
    由一个组件,向下找到最近的指定组件;
    由一个组件,向下找到所有指定的组件;
    由一个组件,找到指定组件的兄弟组件。

    5 个不同的场景,对应 5 个不同的函数,实现原理也大同小异。

    向上找到最近的指定组件——findComponentUpward

    // 由一个组件,向上找到最近的指定组件
    function findComponentUpward (context, componentName) {
      let parent = context.$parent;
      let name = parent.$options.name;
    
      while (parent && (!name || [componentName].indexOf(name) < 0)) {
        parent = parent.$parent;
        if (parent) name = parent.$options.name;
      }
      return parent;
    }
    export { findComponentUpward };
    

    比如下面的示例,有组件 A 和组件 B,A 是 B 的父组件,在 B 中获取和调用 A 中的数据和方法:

    <!-- component-a.vue -->
    <template>
      <div>
        组件 A
        <component-b></component-b>
      </div>
    </template>
    <script>
      import componentB from './component-b.vue';
    
      export default {
        name: 'componentA',
        components: { componentB },
        data () {
          return {
            name: 'Aresn'
          }
        },
        methods: {
          sayHello () {
            console.log('Hello, Vue.js');
          }
        }
      }
    </script>
    
    <!-- component-b.vue -->
    <template>
      <div>
        组件 B
      </div>
    </template>
    <script>
      import { findComponentUpward } from '../utils/assist.js';
    
      export default {
        name: 'componentB',
        mounted () {
          const comA = findComponentUpward(this, 'componentA');
          
          if (comA) {
            console.log(comA.name);  // Aresn
            comA.sayHello();  // Hello, Vue.js
          }
        }
      }
    </script>
    

    向上找到所有的指定组件——findComponentsUpward

    // 由一个组件,向上找到所有的指定组件
    function findComponentsUpward (context, componentName) {
      let parents = [];
      const parent = context.$parent;
    
      if (parent) {
        if (parent.$options.name === componentName) parents.push(parent);
        return parents.concat(findComponentsUpward(parent, componentName));
      } else {
        return [];
      }
    }
    export { findComponentsUpward };
    

    向下找到最近的指定组件——findComponentDownward

    // 由一个组件,向下找到最近的指定组件
    function findComponentDownward (context, componentName) {
      const childrens = context.$children;
      let children = null;
    
      if (childrens.length) {
        for (const child of childrens) {
          const name = child.$options.name;
    
          if (name === componentName) {
            children = child;
            break;
          } else {
            children = findComponentDownward(child, componentName);
            if (children) break;
          }
        }
      }
      return children;
    }
    export { findComponentDownward };
    

    向下找到所有指定的组件——findComponentsDownward

    // 由一个组件,向下找到所有指定的组件
    function findComponentsDownward (context, componentName) {
      return context.$children.reduce((components, child) => {
        if (child.$options.name === componentName) components.push(child);
        const foundChilds = findComponentsDownward(child, componentName);
        return components.concat(foundChilds);
      }, []);
    }
    export { findComponentsDownward };
    

    找到指定组件的兄弟组件——findBrothersComponents

    // 由一个组件,找到指定组件的兄弟组件
    function findBrothersComponents (context, componentName, exceptMe = true) {
      let res = context.$parent.$children.filter(item => {
        return item.$options.name === componentName;
      });
      let index = res.findIndex(item => item._uid === context._uid);
      if (exceptMe) res.splice(index, 1);
      return res;
    }
    export { findBrothersComponents };
    

    相比其它 4 个函数,findBrothersComponents 多了一个参数 exceptMe,是否把本身除外,默认是 true。寻找兄弟组件的方法,是先获取 context. p a r e n t . parent. parent.children,也就是父组件的全部子组件,这里面当前包含了本身,所有也会有第三个参数 exceptMe。Vue.js 在渲染组件时,都会给每个组件加一个内置的属性 _uid,这个 _uid 是不会重复的,借此我们可以从一系列兄弟组件中把自己排除掉。

    Event Bus
    有时候两个组件之间需要进行通信,但是它们彼此不是父子组件的关系。在一些简单场景,你可以使用一个空的 Vue 实例作为一个事件总线中心(central event bus):

     //中央事件总线
        var bus=new Vue();
    
        var app=new Vue({
            el:'#app',
            template:`
                <div>
                    <brother1></brother1>
                    <brother2></brother2>
                </div>
            `
        })
    
    // 在组件 brother1 的 methods 方法中触发事件
    bus.$emit('say-hello', 'world')
    
    // 在组件 brother2 的 created 钩子函数中监听事件
    bus.$on('say-hello', function (arg) {
      console.log('hello ' + arg);          // hello world
    })
    

    vuex处理组件之间的数据交互
    如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。 详情可参考:https://vuex.vuejs.org/zh-cn/

    参考 https://blog.csdn.net/zhoulu001/article/details/79548350
    参考 https://github.com/iview/iview/blob/2.0/src/mixins/emitter.js
    参考 https://github.com/iview/iview/blob/2.0/src/utils/assist.js

    作者:张炳 https://segmentfault.com/a/1190000018241972

    展开全文
  • vuejs组件通信的eventHub(巴士)

    千次阅读 2018-09-11 19:58:46
    但是作为组件之间的通信已经足够了,因为你用vuex不得不引用vuex 而且你还需要做不少的配置,在大型或者中型项目处理起来十分方便。 但是一两个组件之间传递数据,或者组件比较少的情况下还要这样操作,需要一个...

    eventHub以我理解,他有点像vuex

    eventHub是什么?

    但是又是缩小版的,可以说是乞丐版,因为他所操作的东西并不多。

    但是作为组件之间的通信已经足够了,因为你用vuex不得不引用vuex

    而且你还需要做不少的配置,在大型或者中型项目处理起来十分方便。

    但是一两个组件之间传递数据,或者组件比较少的情况下还要这样操作,需要一个备用方案。

     

    eventHub如何使用?

    1.如果你是外部js 引用的话,可以这样写

     

    // event-bus.js
    // 组件通过它来通信
    var eventHub = new Vue()
    export default eventHub
    
    
    // 主页面
    
    <template>
        <div>
            <button @click="find">发送</button>
        </div>
    
    </template>
    <script>
    import Subscriber from './components/Subscriber'   //这里是假设的目录,需要自己定义
    import eventHub from './js/event-bus'              //这里是假设的目录,需要自己定义  
    export default {
       methods:{
            find(){
              eventHub.$emit('delete-todo', 'hello')
                // 第一个参数是信号的名称
                // 第二个参数是发送的参数
            }
        }
    }
    </script>
    
    
    
    
    
    // 组件1  
    // components名称:Subscriber 
    
    <template>
            
    
    
    </template>
    
    <script>
      export default {
        created(){
           eventHub.$on('delete-todo',backing )
            // 这里是接收信号
           // 第一个参数是信号名称
           // 第二个参数是回调的函数名称
        },
         methods:{
            backing(site){
             console.log(site)
            }
        }
    }
    
    </script>
    
    
    
    // 点击按钮「发送」 后
    // 打印: hello
    
    
    
    
    
    

    这里是把他独立成一个js 引用,如果不想每次用的时候都在组件里面定义应该怎么做呢?

     

    1.在入口文件里面引用

     

    假设你用的是脚手架工具,引用文件名叫 main.js

    import Vue from 'vue'
    import App from './App'
    
    
    //  全局组件之间通信
    Vue.prototype.$eventHub= Vue.prototype.$eventHub ||  new Vue()        // 巴士
    
    new Vue({
      el: '#app',
      template: '<App/>',
      components: {App},
      data: {
        eventHub: new Vue()
      }
    })
    
    
    
    

    组件部分:

    主页面: HelloWorld.vue

    <template>
      <div class="hello">
        <h1 @click="go">传递</h1>
        <back></back>
      </div>
    </template>
    
    <script>
    import back from "@/components/Background";
    export default {
      name: "HelloWorld",
      methods: {
        go() {
          this.$eventHub.$emit("add-todo", "哈哈");
        }
      },
      components: {
        back
      }
    };
    </script>
    

     

    引用组件:

    <template>
        <div>
            <div>background</div>
            <div class="">
                <button @click="move">发送bb</button>
            </div>
        </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          bb: "我是订阅者"
        };
      },
      created() {
        this.$eventHub.$on("add-todo", this.move);
        // 绑定接收回调过来的事件处理 
      },
      methods: {
        move(ab) {
          console.log("发送");
          console.log(ab);
          console.log("我获取到参数");
        }
      }
    };
    </script>
    
    <style>
    </style>
    

     

    最终打印:

    发送
    哈哈
    我获取的参数

     

     

     

    展开全文
  • 类型一、父组件传递数据到子组件 方法1:通过prop进行传值 例:

    类型一、父组件到子组件

    1、父组件传值到子组件,通过prop进行传值操作,如下:
    parent.vue:
    <child :childInfo="parentInfo"></child>
    其中parentInfo为parent页面定义的data数据
    
    child.vue:
    定义prop,如prop:['childInfo'],该处的childInfo为parent页面中所定义,至此prop传值已完毕;
    此时在child页面可以使用this.childInfo来获取从父页面传递过来的值。
    
    2、父组件调用子组件的属性及方法等,通过在父组件使用的子组件中定义ref,如下:
    parent.vue:
    <child :childInfo="parentInfo" ref="childRef"></child>
    在parent的child组件定义了ref之后,可以在parent页面的任意地方通过使用this.$refs.childRef来调用子组件的属性和方法,
    也就是说this.$refs.childRef相当于child页面中的this。
    

    类型二、子组件到父组件

    1、子组件传值到父组件,具体如下:
    child.vue:
    在子页面如果需要传递数据到父组件,可在需要传值的地方通过this.$emit('方法名(如childMethod)','数据(如childData)');
    然后在父组件来监听刚刚定义的方法
    
    parent.vue
    <child @childMethod="parentMethod"></child>
    此处的parentMethod为在parent页面定义的方法,在此方法中可以将定义参数,用来接收子组件传递过来的数据,如下:
    parentMehod(dataParam) {
    	console.log(dataParam);
    }
    此处的dataParam为child页面中通过$emit传递的childData。
    
    2、子组件调用父组件的方法,有两种,笔者推荐第一种,具体如下:
    1)、第一种方法类似于子组件传值到父组件,只是这里这里的parentMethod为你所需要调用的方法,其余的操作与上述所说无异;
    2)、第二种方法则是在子组件需要调用父组件方法或属性的地方通过(this.$parent.父组件属性或方法)的形式来获取父组件的属性
    或父组件的方法。
    

    写在最后:笔者文采不好,有问题的地方希望指出,另外如果有什么问题可以留言或私信,我们可以一起探讨。

    展开全文
  • 主要介绍了Vuejs第十篇之vuejs父子组件通信的相关资料,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
  • 本篇文章主要介绍了vue父子组件通信 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • vuejs组件之间的通信

    2020-06-01 18:14:05
    3:父组件 data 定义一个数据,冒号为动态传值 obj: { name: 'name', age: 18 } 二:子 ==> 父,$emit 1:子组件里面,methods 定义一个方法 handleSuccess () { // 子 ==> 父 组件通信,数据自定义 this.$emit('to...
  • Vuejs(二):Vuejs组件

    2019-11-10 13:44:44
    Vuejs组件一:初识组件二:全局组件和局部组件三:父组件与子组件四:注册组件语法糖五:模板的分离写法六:组件中的数据七:父子组件通信7.1 父传子(props)7.2 props数据验证7.3 props驼峰标识问题7.4 子传父...
  • VueJS-组件通信

    2017-10-23 22:25:34
    下面介绍几种常用的组件通信方式,包括父子组件,兄弟组件,复杂组件下的不同通信方式 现代通信方式: FLUX VUEX FLUX将一个应用分成四个部分:文档 View: 视图层Action(动作):视图层发出的消息(比如...
  • Vuejs 组件

    2020-09-12 23:53:47
    组件的基本使用 2.0版本以前 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vuejs</title> <script src="js/vue.js"></script> <...
  • vuejs父子组件通信

    2017-02-11 16:44:59
    “prop” 是组件数据的一个字段,期望从父组件传下来。子组件需要显式地用 props 选项 声明 props: 在子组件 jade模板中,书写 ``` .hot-item-container(@click="openHotPlugins(item.appkey)") ``` 在子组件 ...
  • 主要介绍了VueJs组件之父子通讯的方式,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
  • 一:父组件主动向子组件传值 (1)在调用子组件的地方绑定动态数据(也可以传递付父组件方法给子组件,方式一样) <v-childcomp :parentMsg="parentMsg"></v-childcomp> (2)子组件通过props接受...
  • VueJS兄弟组件通信

    千次阅读 2017-06-14 13:42:22
    on和emit的事件必须是在一个公共的实例上,才能触发。 我的解决方案是: ...Test.vue组件内调用 import { bus } from 'bus.js' // ... bus.$emit( 'tip' , '123' )
  • 深入理解 Vuejs 组件

    2018-09-11 22:09:00
    本文主要归纳在 Vuejs 学习过程中对于 Vuejs 组件的各个相关要点。由于本人水平有限,如文中出现错误请多多包涵并指正,感谢。如果需要看更清晰的代码高亮,请跳转至我的个人站点的深入理解 Vuejs 组件查看本文。 ...
  • 本文主要归纳在 Vuejs 学习过程中对于 Vuejs 组件的各个相关要点。由于本人水平有限,如文中出现错误请多多包涵并指正,感谢。组件使用细节name 属性在给子组件定义属性的时候,通常第一个属性就是 name 。例如下面...
  • vuejs组件

    2018-09-04 21:46:00
    组件和子组件通信需要怎么做? 需要发布订阅模式来做这个事情,子组件注册一个事件,父组件进行监听 < div id ='root' >   < input v-model ='inputValue' />   < button @click ='handleSubmit'...
  • Vuejs组件化开发

    2021-02-09 22:13:42
    组件化开发01-组件化开发01-组件化开发的基本使用02-全局组件和局部组件03-父组件和子组件04-组件的语法糖注册方式05-组件模块的分离写法06-组件中的数据存放问题07-组件通信-父组件向子组件传递参数08-组件通信-子...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,047
精华内容 1,218
关键字:

vuejs组件通信

vue 订阅