zoukankan      html  css  js  c++  java
  • Vue.js入门(6)组件间通信

    序言

    如果你了解过JavaScript的设计模式一一观察者模式,一定知道dispatchEvent和addEventListener这两个方法。

    Vue组件也有与之类似的一套模式,子组件用$emit()来触发事件,父组件用$on()来监昕子组件的事件。

    父传子

    通过prop实现通信

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <meta charset="utf-8" />
        <script type="text/javascript" src="../../assets/js/vue.js"></script>
    </head>
    <body>
    
        <div id="app">
            <div>{{pmsg}}</div>
            <child title='来自父组件的值'></child>
          </div>
        
          <template id="childtmpl">
            <div>
                <div>{{msg}}-{{title}}</div>
            </div>
          </template>
    
          <script type="text/javascript">
          //子组件
            Vue.component('child', {
              props: ['title'],
              data: function() {
                return {
                  msg: '子组件本身的数据'
                }
              },
              template: '#childtmpl'
            });
    
            //父组件
            var vm = new Vue({
              el: '#app',
              data: {
                pmsg: '父组件',
              }
            });
          </script>
    </body>
    </html>
    View Code

    子传父

    子组件用$emit()触发事件

    $emit()第一个参数为自定义的事件名称第二个参数为需要传递的数据

    父组件用v-on监听子组件的事件

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <meta charset="utf-8" />
        <script type="text/javascript" src="../../assets/js/vue.js"></script>
    </head>
    <body>
    
        <!--父组件 -->
        <div id="app">
            <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
            <child  @father-enlarge-text='fatherfunction($event)'></child>
        </div>
    
        <!-- 子组件 -->
          <template id="childtmpl">
            <div>
                <button @click='sonfunction'>子传父</button>
              </div>
          </template>
    
          <script type="text/javascript">
          
            Vue.component('child', {
              template: '#childtmpl'
              ,
              methods: {
                sonfunction: function(val){
                  this.$emit("father-enlarge-text", 5)
                }
              }
            });
    
            var vm = new Vue({
              el: '#app',
              data: {
                pmsg: '父组件',
                fontSize: 10
              },
              methods: {
                fatherfunction: function(val){
                  this.fontSize += val;
                }
              }
            });
          </script>
        
    </body>
    </html>
    View Code

    兄弟传

    在Vue.2.x中,推荐使用一个空的Vue实例作为中央事件总线(bus),也就是一个中介。

    这种方法巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级,而且Vue1.x和Vue2.x都适用。


    兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据

    提供事件中心 var hub = new Vue()

    传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)

    接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名

    销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <meta charset="utf-8" />
        <script type="text/javascript" src="../../assets/js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <div>父组件</div>
            <div>
              <button @click='handle'>销毁事件</button>
            </div>
            <borther-a></borther-a>
            <borther-b></borther-b>
        </div>
    
        <template id="Atmpl">
            <div>
                <div>a:{{num}}</div>
                <div>
                  <button @click='handle'>点击</button>
                </div>
              </div>
          </template>
    
    
          <template id="Btmpl">
            <div>
                <div>b:{{num}}</div>
                <div>
                  <button @click='handle'>点击</button>
                </div>
              </div>
          </template>
    
    
          <script type="text/javascript">
    
            //1、 中央事件总线
            var bus = new Vue();
        
            Vue.component('borther-a', {
              data: function(){
                return {
                  num: 0
                }
              },
              template: '#Atmpl',
              methods: {
                handle: function(){
                  //2、传递数据方,通过一个事件触发bus.$emit(方法名,传递的数据)   触发兄弟组件的事件
                  bus.$emit('b-event', 2);
                }
              },
              mounted: function() {
               // 3、接收数据方,通过mounted(){}钩子中触发bus.$on(方法名
                bus.$on('a-event', (val) => {
                  this.num += val;
                });
              }
            });
    
         Vue.component('borther-b', {
          data: function(){
            return {
              num: 0
            }
          },
          template: '#Btmpl',
          methods: {
            handle: function(){
              //2、传递数据方,通过一个事件触发bus.$emit(方法名,传递的数据)触发兄弟组件的事件
              bus.$emit('a-event', 1);
            }
          },
          mounted: function() {
            // 3、接收数据方,通过mounted(){}钩子中触发bus.$on()方法名
            bus.$on('b-event', (val) => {
              this.num += val;
            });
          }
        });
        var vm = new Vue({
          el: '#app',
          data: {},
          methods: {
            handle: function(){
              //4、销毁事件 通过bus.$off()方法名销毁之后无法进行传递数据  
              bus.$off('a-event');
              bus.$off('b-event');
            }
          }
        });
        </script>
    </body>
    </html>
    View Code

    当你的项目比较大,有更多的小伙伴参与开发时,也可以选择更好的状态管理解决方案vuex

    除了中央事件总线bus外,还有两种方法可以实现组件间通信:父链和子组件索引

    父链

    在子组件中,使用this.$parent可以直接访问该组件的父实例或组件,父组件也可以通过this.$children访问它所有的子组件,而且可以递归向上或向下无线访问,直到根实例或最内层的组件。

    尽管Vue允许这样操作,但在业务中,子组件应该尽可能地避免依赖父组件的数据,更不应该去主动修改它的数据,因为这样使得父子组件紧藕合,只看父组件,很难理解父组件的状态,因为它可能被任意组件修改,理想情况下,只有组件自己能修改它的状态。父子组件最好还是通过props和$emit来通信。

    子组件索引

    当子组件较多时,通过this.$children来一一遍历出我们需要的一个组件实例是比较困难的,尤其是组件动态渲染时,它们的序列是不固定的。Vue提供了子组件索引的方法,用特殊的属性ref来为子组件指定一个索引名称。

    在父组件模板中,子组件标签上使用ref指定一个名称,井在父组件内通过this.$refs来访问指定名称的子组件。

    $refs只有渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案,应当避免在模板或计算属性中使用础。

    资料

    https://www.jb51.net/article/140581.htm

  • 相关阅读:
    API接口签名验证2
    jps看不到进程号 规格严格
    XP Administrator账户没有了?显示欢迎屏幕下所隐藏的Administrator账户 规格严格
    PDH 规格严格
    plugin.xml 规格严格
    强大的备份软件 规格严格
    关于工具使用 规格严格
    java.library.path属性在代码中设置不生效问题 规格严格
    RCP 规格严格
    Linux下信息查询 规格严格
  • 原文地址:https://www.cnblogs.com/cnki/p/13233808.html
Copyright © 2011-2022 走看看