vue組件之間的傳值

組件

組件可以大致的分爲三類

  • 父組件
  • 子組件
  • 兄弟組件

當使用組件時,往往可能會遇到這樣的問題
如果我想通過父組件向子組件傳值,我應該怎麼辦?
同樣的道理,子組件向父組件傳值怎麼辦?

組件之間傳值也可以分爲三類

  • 父組件向子組件傳值
  • 子組件向父組件傳值
  • 兩個兄弟之間的組件傳值

父組件向子組件傳值

父組件以屬性的形式將要傳遞的值綁定到子組件身上,然後子組件再通過props屬性接收傳遞的值

<div id="app">
  // 將要傳遞的值綁定在屬性上
  <cpn :title="msg" :num1="num" num2="num" :arr1="arr" arr2="arr"></cpn>
</div>

<script>
Vue.component('cpn', {
  // 利用 props 屬性接收傳遞的值
  props: ['title', 'num1', "num2", 'arr1', 'arr2'],
  data() {
    return {
      msg: '子組件'
    }
  },
  template: `
    <div>
      <div>{{msg}}</div>
      <div>{{title}}</div>
      <div>{{typeof num1}}</div>
      <div>{{typeof arr2}}</div>
      <li v-for="item in arr1">{{item}}</li>
      <li v-for="item in arr2">{{item}}</li>
    </div
  `
})
new Vue({
  el: '#app',
  data: {
    msg: '父組件',
    num: 1,
    arr: ['張三', '李四', '王麻子'],
    obj: {
      name: '張三',
      age: 18
    }
  }
})

在這裏插入圖片描述
注意
1.傳的值可以是數字、對象、數組等,傳的值動態綁定(v-bind:)和靜態綁定是有區別的,靜態綁定傳遞的值的類型最終都會變成字符串類型,另外如果對這個值進行遍歷的話,動態綁定的值(假如是數組),那麼將會將數組的每一項輸出,但如果是靜態綁定的話,將會把傳遞的值的名稱打印(arr),具體看上面的例子

2.在props中使用駝峯形式,模板的名字需要使用短橫線的形式,字符串形式的模板中沒有這個限制
3.單向綁定

子組件向父組件傳值

子組件向父組件傳值主要是通過事件監聽的方式來實現的

子組件使用$emait來觸發事件,然後父組件通過v-on來監聽子組件的事件
$emit的第一個參數用來自定義事件的名稱,第二個參數用來傳遞要傳遞的值

<div id="app">
  <div>子組件傳過來的內容是:{{msg}}</div>
  <!-- 父組件監聽子組件的事件 -->
  <cpn @post-data="handle($event)"></cpn>
</div>
<script>
Vue.component('cpn', {
  data() {
    return {
      msg: '我是子組件傳過來的內容'
    }
  },
  // 子組件使用 $emit 來觸發事件
  template: `
  <div>
    <div>11111111</div>
    <button @click='$emit("post-data", msg)'>按鈕</button>
  </div>
  `
})
var vm = new Vue({
  el: '#app',
  data: {
    msg: ''
  },
  methods: {
    handle(value) {
      this.msg = value;
    }
  }
})
</script>

在這裏插入圖片描述

兄弟組件之間傳值

兄弟組件之間的傳值主要藉助於事件中心來傳值

主要步驟:
1.提供事件中心var hub = new Vue()
2.傳遞數據,通過觸發hub.$emit(方法名, 傳遞的值)
事件來傳遞值
3.接收數據,在mounted(){}鉤子中,通過觸發```hub.$off()``方法來接收數據

4.另外,還可以通過hub.$off(name)方法l來銷燬,銷燬之後就無法進行傳遞值了

<div id="app">
    <div>父組件</div>
    <div>
      <button @click='handle'>銷燬事件</button>
    </div>
    <test-tom></test-tom>
    <test-jerry></test-jerry>
  </div>
  <script>
    //1、 提供事件中心
    var hub = new Vue();

    Vue.component('test-tom', {
      data: function(){
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>TOM:{{num}}</div>
          <div>
            <button @click='handle'>點擊</button>
          </div>
        </div>
      `,
      methods: {
        handle: function(){
          //2、傳遞數據方,通過一個事件觸發hub.$emit(方法名,傳遞的數據)   觸發兄弟組件的事件
          hub.$emit('jerry-event', 2);
        }
      },
      mounted: function() {
       // 3、接收數據方,通過mounted(){} 鉤子中  觸發hub.$on(方法名
        hub.$on('tom-event', (val) => {
          this.num += val;
        });
      }
    });
    Vue.component('test-jerry', {
      data: function(){
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>JERRY:{{num}}</div>
          <div>
            <button @click='handle'>點擊</button>
          </div>
        </div>
      `,
      methods: {
        handle: function(){
          //2、傳遞數據方,通過一個事件觸發hub.$emit(方法名,傳遞的數據)   觸發兄弟組件的事件
          hub.$emit('tom-event', 1);
        }
      },
      mounted: function() {
        // 3、接收數據方,通過mounted(){} 鉤子中  觸發hub.$on()方法名
        hub.$on('jerry-event', (val) => {
          this.num += val;
        });
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {
        
      },
      methods: {
        handle: function(){
          //4、銷燬事件 通過hub.$off()方法名銷燬之後無法進行傳遞數據  
          hub.$off('tom-event');
          hub.$off('jerry-event');
        }
      }
    });
  </script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章