1. 程式人生 > 其它 >Vue中父子元件之間相互傳值的方法

Vue中父子元件之間相互傳值的方法

父子元件的通訊

在實際開發中,往往一些資料確實需要從上層傳遞到下層:
1. 比如開發一個頁面中,我們從伺服器請求到了許多資料。
2. 其中一部分資料,並非是我們整個頁面的大元件來展示的,而是需要下面的子元件進行展示。
3. 這個時候,並不會讓子元件再發送一次網路請求,而是直接讓大元件(父元件)將資料傳遞給小元件(子元件)。

資料傳遞

  • 通過props向子元件傳遞資料

  • 通過事件向父元件傳送訊息

  • 父元件通過屬性的方式給子元件傳值

  • 子元件使用props接收父元件傳遞的屬性

注意:
Vue例項就是根元件,也叫root元件 !

父傳子

props基本用法

  • 在元件中,使用選項props來宣告需要從父級接受到的資料
  • props的值有兩種方式:
    • 方式一:字串陣列,陣列中的字串就是傳遞時的名稱.
    • 方式二:物件,物件可以設定傳遞時的型別,也可以設定預設值等.
  1. 方式一傳值
<body>
  <div id="app">
    <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
  </div>

  <template id="cpn">
    <div>
      <p v-for="item in cmovies">{{item}}</p>
      <h2>{{cmessage}}</h2>
    </div>
  </template>

  <script>
    //父傳子:props
    const cpn = {
      template: '#cpn',
      props: ['cmovies', 'cmessage'],
    }

    const app = new Vue({
      el: '#app',
      data: {
        message: '你好呀',
        movies: ['海王', '海賊王', '海爾兄弟']
      },
      components: {
        cpn
      }
    })
  </script>
</body>

注意: cpn元件的註冊增強寫法

  1. 方式二傳值
  • 在前面,我寫的props選項是一個數組.除了陣列之外還可以使用物件,當需要對props進行型別等驗證時,就需要使用物件寫法了.
  • 支援的資料型別如下,同時也支援我們自己寫的型別
String Number
Boolean Array
Object Date
Function Symnbol
<body>
  <div id="app">
    <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>  這裡使用v-bind將值繫結
  </div>

  <template id="cpn">
    <div>
      <p v-for="item in cmovies">{{item}}</p>
      <h2>{{cmessage}}</h2>
    </div>
  </template>

  <script>
    //父傳子:props
    const cpn = {
      template: '#cpn',
      // props: ['cmovies', 'cmessage'], 
      props: {
        //1. 型別限制
        // cmovies: Arry,
        // cmessage: String,
        // 2. 提供一些預設值,以及必傳值
        cmessage: {
          type: String,
          default: '我是預設值',
          requierd: 'true'
        },
        //型別是物件或者是陣列時,預設值必須是一個函式。
        cmovies: {
          type: Array,
          default() {
            return []
          }
        },
      }
    }

    const app = new Vue({
      el: '#app',
      data: {
        message: '你好呀',
        movies: ['海王', '海賊王', '海爾兄弟']
      },
      components: {
        cpn
      }
    })
  </script>
</body>

Prop的大小寫

  1. 如果在呼叫元件的時候使用了小駝峰命名的屬性,那麼在props中的命名需要全部小寫。
  2. 如果在props中的命名採用小駝峰的方式,那麼在呼叫元件的標籤中需要使用其等價的短橫線分隔的命名方式來命名屬性。
<body>
  <div id="app">
    <cpn :finfo="info" :child-meassage="message"></cpn>    重點看這裡!
  </div>

  <template id="cpn">
    <div>
      <h2>{{finfo}}</h2>
      <h2>{{childMeassage}}</h2>
    </div>
  </template>

  <script>
    const cpn = {
      template: '#cpn',
      props: {
        finfo: {
          type: Object,
          default() {
            return {}
          }
        },
        childMeassage: {
          type: String,
          default() {
            return {}
          }
        }
      }
    }
    const app = new Vue({
      el: '#app',
      data: {
        info: {
          name: 'why',
          age: 18,
          height: 1.88
        },
        message: 'aaaaa'
      },
      components: {
        cpn
      }

    })
  </script>
</body>

總結:在元件裡使用的值如果用駝峰命名,那麼在繫結時,就需要在將大寫字母轉換成小寫字母並在前面加“-”

子傳父(自定義事件)

  • v-on不但可以用來監聽DOM事件,也可以用來監聽自定義事件。
  • 自定義事件的流程:
  1. 在子元件中,通過$emti()來觸發事件
  2. 在父元件中,通過v-on來監聽元件事件
<body>
  <!-- 父元件模板 -->
  <div id="app">
    <!-- 父元件監聽子元件發過來的事件 -->
    <cpn @itemclick="cpnClick"></cpn>     這裡使用v-on來監聽自定義事件,並在vue例項中,做出響應。
  </div>

  <!-- 子元件模板 -->
  <template id="cpn">    
    <div>
      <button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
    </div>
  </template>

  <script>
    //1. 子元件
    const cpn = {
      template: '#cpn',
      data() {
        return {
          categories: [
            {
              id: '1',
              name: '熱門推薦'
            },
            {
              id: '2',
              name: '計生情趣'
            },
            {
              id: '3',
              name: '電腦辦公'
            },
            {
              id: '4',
              name: '手機數碼'
            },
          ]
        }
      },
      methods: {
        btnClick(item) {
          // 自定義事件,把item傳給父元件,發射事件
          this.$emit('itemclick', item)
        }
      }

    }

    //2. 父元件
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好呀'
      },
      components: {
        cpn
      },
      methods: {
        cpnClick(item) {
          //處理事件
          console.log('cpnClick', item);
        }
      }
    })
  </script>
</body>