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)
            },

猜你喜欢

转载自blog.csdn.net/qq_41337100/article/details/106016381