国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue.js入門(3)――詳解組件通信

2019-11-19 18:43:20
字體:
來源:轉載
供稿:網友

本文介紹vue.js組件,具體如下:

5.2 組件通信

盡管子組件可以用this.$parent訪問它的父組件及其父鏈上任意的實例,不過子組件應當避免直接依賴父組件的數據,盡量顯式地使用 props 傳遞數據。另外,在子組件中修改父組件的狀態是非常糟糕的做法,因為:

1.這讓父組件與子組件緊密地耦合;

2.只看父組件,很難理解父組件的狀態。因為它可能被任意子組件修改!理想情況下,只有組件自己能修改它的狀態。

每個Vue實例都是一個事件觸發器:

  • $on()――監聽事件。
  • $emit()――把事件沿著作用域鏈向上派送。(觸發事件)
  • $dispatch()――派發事件,事件沿著父鏈冒泡。
  • $broadcast()――廣播事件,事件向下傳導給所有的后代。

5.2.1 監聽與觸發

v-on監聽自定義事件:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title></title>  </head>  <body>    <!--子組件模板-->    <template id="child-template">      <input v-model="msg" />      <button v-on:click="notify">Dispatch Event</button>    </template>    <!--父組件模板-->    <div id="events-example">      <p>Messages: {{ messages | json }}</p>      <child v-on:child-msg="handleIt"></child>    </div>  </body>  <script src="js/vue.js"></script>  <script>//    注冊子組件//    將當前消息派發出去    Vue.component('child', {      template: '#child-template',      data: function (){        return { msg: 'hello' }      },      methods: {        notify: function() {          if(this.msg.trim()){            this.$dispatch('child-msg',this.msg);            this.msg = '';          }        }      }    })//    初始化父組件//    在收到消息時將事件推入一個數組中    var parent = new Vue({      el: '#events-example',      data: {        messages: []      },      methods:{        'handleIt': function(){          alert("a");        }      }    })  </script></html>

父組件可以在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title></title>  </head>  <body>    <div id="counter-event-example">     <p>{{ total }}</p>     <button-counter v-on:increment="incrementTotal"></button-counter>     <button-counter v-on:increment="incrementTotal"></button-counter>    </div>  </body>  <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>  <script type="text/javascript">    Vue.component('button-counter', {     template: '<button v-on:click="increment">{{ counter }}</button>',     data: function () {      return {       counter: 0      }     },     methods: {      increment: function () {       this.counter += 1       this.$emit('increment')      }     },    })    new Vue({     el: '#counter-event-example',     data: {      total: 0     },     methods: {      incrementTotal: function () {       this.total += 1      }     }    })  </script></html>

在某個組件的根元素上監聽一個原生事件。可以使用 .native 修飾v-on 。例如:

<my-component v-on:click.native="doTheThing"></my-component>

5.2.2 派發事件――$dispatch()

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title></title>  </head>  <body>    <div id="app">      <p>Messages: {{ messages | json }}</p>      <child-component></child-component>    </div>    <template id="child-component">      <input v-model="msg" />      <button v-on:click="notify">Dispatch Event</button>    </template>  <script src="js/vue.js"></script>  <script>    // 注冊子組件    Vue.component('child-component', {      template: '#child-component',      data: function() {        return {          msg: ''        }      },      methods: {        notify: function() {          if (this.msg.trim()) {            this.$dispatch('child-msg', this.msg)            this.msg = ''          }        }      }    })      // 初始化父組件    new Vue({      el: '#app',      data: {        messages: []      },      events: {        'child-msg': function(msg) {          this.messages.push(msg)        }      }    })  </script>  </body></html>

  1. 子組件的button元素綁定了click事件,該事件指向notify方法
  2. 子組件的notify方法在處理時,調用了$dispatch,將事件派發到父組件的child-msg事件,并給該該事件提供了一個msg參數
  3. 父組件的events選項中定義了child-msg事件,父組件接收到子組件的派發后,調用child-msg事件。

 5.2.3 廣播事件――$broadcast()

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title></title>  </head>  <body>    <div id="app">      <input v-model="msg" />      <button v-on:click="notify">Broadcast Event</button>      <child-component></child-component>    </div>        <template id="child-component">      <ul>        <li v-for="item in messages">          父組件錄入了信息:{{ item }}        </li>      </ul>    </template>  <script src="js/vue.js"></script>  <script>    // 注冊子組件    Vue.component('child-component', {      template: '#child-component',      data: function() {        return {          messages: []        }      },      events: {        'parent-msg': function(msg) {          this.messages.push(msg)        }      }    })    // 初始化父組件    new Vue({      el: '#app',      data: {        msg: ''      },      methods: {        notify: function() {          if (this.msg.trim()) {            this.$broadcast('parent-msg', this.msg)          }        }      }    })  </script>  </body></html>

和派發事件相反。前者在子組件綁定,調用$dispatch派發到父組件;后者在父組件中綁定,調用$broadcast廣播到子組件。

 5.2.4 父子組件之間的訪問

  • 父組件訪問子組件:使用$children或$refs
  • 子組件訪問父組件:使用$parent
  • 子組件訪問根組件:使用$root

$children:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title></title>  </head>  <body>    <div id="app">      <parent-component></parent-component>    </div>        <template id="parent-component">      <child-component1></child-component1>      <child-component2></child-component2>      <button v-on:click="showChildComponentData">顯示子組件的數據</button>    </template>        <template id="child-component1">      <h2>This is child component 1</h2>    </template>        <template id="child-component2">      <h2>This is child component 2</h2>    </template>    <script src="js/vue.js"></script>    <script>      Vue.component('parent-component', {        template: '#parent-component',        components: {          'child-component1': {            template: '#child-component1',            data: function() {              return {                msg: 'child component 111111'              }            }          },          'child-component2': {            template: '#child-component2',            data: function() {              return {                msg: 'child component 222222'              }            }          }        },        methods: {          showChildComponentData: function() {            for (var i = 0; i < this.$children.length; i++) {              alert(this.$children[i].msg)            }          }        }      })          new Vue({        el: '#app'      })    </script>  </body></html>

$ref可以給子組件指定索引ID:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title></title>  </head>  <body>    <div id="app">      <parent-component></parent-component>    </div>        <template id="parent-component">      <!--<child-component1></child-component1>      <child-component2></child-component2>-->      <child-component1 v-ref:cc1></child-component1>      <child-component2 v-ref:cc2></child-component2>      <button v-on:click="showChildComponentData">顯示子組件的數據</button>    </template>        <template id="child-component1">      <h2>This is child component 1</h2>    </template>        <template id="child-component2">      <h2>This is child component 2</h2>    </template>    <script src="js/vue.js"></script>    <script>      Vue.component('parent-component', {        template: '#parent-component',        components: {          'child-component1': {            template: '#child-component1',            data: function() {              return {                msg: 'child component 111111'              }            }          },          'child-component2': {            template: '#child-component2',            data: function() {              return {                msg: 'child component 222222'              }            }          }        },        methods: {          showChildComponentData: function() {//            for (var i = 0; i < this.$children.length; i++) {//              alert(this.$children[i].msg)//            }            alert(this.$refs.cc1.msg);            alert(this.$refs.cc2.msg);          }        }      })      new Vue({        el: '#app'      })    </script>  </body></html>

 

效果與$children相同。

$parent:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title></title>  </head>  <body>    <div id="app">      <parent-component></parent-component>    </div>        <template id="parent-component">      <child-component></child-component>    </template>        <template id="child-component">      <h2>This is a child component</h2>      <button v-on:click="showParentComponentData">顯示父組件的數據</button>    </template>        <script src="js/vue.js"></script>    <script>      Vue.component('parent-component', {        template: '#parent-component',        components: {          'child-component': {            template: '#child-component',            methods: {              showParentComponentData: function() {                alert(this.$parent.msg)              }            }          }        },        data: function() {          return {            msg: 'parent component message'          }        }      })      new Vue({        el: '#app'      })    </script>  </body></html>

如開篇所提,不建議在子組件中修改父組件的狀態。

 5.2.5 非父子組件通信

有時候非父子關系的組件也需要通信。在簡單的場景下,使用一個空的 Vue 實例作為中央事件總線:

var bus = new Vue()// 觸發組件 A 中的事件bus.$emit('id-selected', 1)// 在組件 B 創建的鉤子中監聽事件bus.$on('id-selected', function (id) {  // ...})

在更多復雜的情況下,可以考慮使用專門的 狀態管理模式。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海安县| 察哈| 彰武县| 依兰县| 唐海县| 南京市| 肥城市| 孝感市| 宣汉县| 太白县| 托克逊县| 彭泽县| 永春县| 大余县| 泽州县| 克山县| 攀枝花市| 随州市| 驻马店市| 河间市| 砚山县| 鄱阳县| 石渠县| 双城市| 宁南县| 桑日县| 库伦旗| 石城县| 甘洛县| 梅州市| 广宁县| 永德县| 宿迁市| 太谷县| 丹凤县| 云南省| 滦平县| 滦平县| 资兴市| 德清县| 蓝山县|