VUE:父子間通過props和emit通信

這裏假設一個背景。
父組件:購物車頁面。
子組件:購物車裏面的每一個商品的item。
父組件需要爲子組件提供數據(商品類型、商品價格、商品標籤等)。父組件無須額外定義說明這些數據,在子組件調用的地方(item的標籤內)直接調用就行。等號的左邊也就是傳入子組件的屬性,比如說key,index,num,thumb…,而等號的右邊就是這些屬性傳入的數據,也就是他們的值。

<!--每一個添加的商品,list裏面是購物車的全部的數據,這裏的index則是加入購物車的商品的序列號-->
        <Item
                v-for="(item,idx) in list"
                :key="idx"
                :index="idx"
                :num="item.num"
                :thumb="item.thumb"
                :title="item.title"
                :desc="item.desc"
                :tag="item.tag"
                :tags="item.tags"
                :originPrice="item.originPrice"
                :price="item.price"
                :isChecked="item.isChecked"
                @input="handleItemSelect"
                @handleDelete="handleDelete"
        />

子組件呢需要在export default裏面設置props來聲明將接收哪些屬性(index,thumb等)和這些屬性的類型。這樣props裏面的屬性的值將自動流入。在template中就可以直接調用這些變量(index,thumb等)。

  props: {
    index: Number,
    thumb: String,
    title: String,
    desc: String,
    tag: String,
    tags: Array,
    originPrice: Number,
    price: Number,
    num: Number,
    isChecked: {
      type: Boolean,
      default: false
    }

這裏是template的調用部分,就作爲數據直接傳入van-card中去了:

    <van-swipe-cell style="width:100%" :before-close="beforeClose">
      <van-card
        :num="num"
        :tag="tag"
        :price="price"
        :desc="desc"
        :title="title"
        :thumb="thumb"
        :origin-price="originPrice"
      >
        <template #tags>
          <van-tag
            plain
            type="danger"
            v-for="(item,idx) in tags"
            :key="idx"
            style="margin-right:4px"
          >{{item}}</van-tag>
        </template>
        <template #footer>
          <van-stepper v-model="value"
                       input-width="40px"
                       button-size="20px"
                       disable-input />
        </template>
      </van-card>
      <template #right>
        <van-button square text="刪除" type="danger" class="delete-button" />
      </template>
    </van-swipe-cell>

那如果子組件想向父組件發送信息,就通過emit。
比如說每一個item裏面有個可以勾選的屬性,這個屬性要傳給購物車組件,爲了全選的功能:

    <van-checkbox
      icon-size="18px"
      checked-color="blue"
      v-model="checked"
      style="padding:0 10px 0 16px"
    ></van-checkbox>

因爲傳遞的數據除了是像data一樣,還可以是compute中的數據,set部分向父組件發送input變量,值爲{ val, idx: this.index }也就是當前這個商品的{checked,index}

  model: {
    prop: 'isChecked'
  },
  computed: {
    //checked屬性發生改變時自動觸發get,當修改監控的屬性時候纔會觸發set
    //val的值就是指向了checked屬性,先set改變checked相關聯的屬性,再get返回checked的值
    checked: {
      get() {
        return this.isChecked
      },
      set(val) {
        this.$emit('input', { val, idx: this.index })
      }
    }
  },

然後父組件需要同名的動態屬性來接收這個值:
在這裏插入圖片描述
然後接收的屬性作爲函數的默認的參數被使用,就是這裏的playload。

            // 單選
            handleItemSelect(playload) {
                const {val, idx} = playload
                const newval = this.list[idx]
                newval.isChecked = val
                this.$set(this.list, idx, newval)
            },
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章