vue中$attrs $listeners你会用吗?

简单来说:$attrs$listeners 是两个「对象」,$attrs 里存放的是父组件中绑定的非 Props 属性,$listeners里存放的是父组件中绑定的非原生事件。

//子组件   
//$attrs 可以收集父组件中的所有传过来的属性 除了那些在组件中没有通过 props 定义的。
//唯一缺点 没在props定义的属性 会显示在生成的html标签上
//解决办法:通过inheritAttrs:false,避免顶层容器继承属性

<template>
  <el-dialog
    :title="title"
    :visible="dialogVisible"
    @close="$emit('update:dialogVisible', false)"
    :width="width"
    :close-on-click-modal="modal"
    v-bind="$attrs"  /**关键代码**
  >
    <slot name="dialog-body"></slot>

    <div slot="footer" class="dialog-footer">
      <slot name="modal-footer">
        <el-button @click="$emit('update:dialogVisible', false)">取 消</el-button>
        <el-button type="primary" @click="$emit('confirm')" size="small">确 定</el-button>
      </slot>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: "my-dialog",
  inheritAttrs:false #关键代码
  props: {
    dialogVisible: Boolean,
    title: String,
    width: {
      type: String,
      default: "500px"
    },
    modal: {
      type: Boolean,
      default: false
    }
  }
};
</script>
//父组件 里使用
//:fullscreen="true" 并没在子组件props内定义 依然传入了子组件
//让dialog 全屏
 <my-dialog :fullscreen="true" :dialogVisible.sync="flag" @confirm="close" title="测试弹框"></my-dialog>

其他例子

//componentA
<template>
  <div class="component-a">
    <component-b :name="name" :tag="tag" :age="age" @click.native="say" @mouseover="sing"></component-b>
  </div>
</template>

<script>
import componentB from "./ComponentB";
export default {
  name: "componentA",
  components: { componentB },
  data() {
    return {
      name: "六哥",
      tag: "帅",
      age: 18
    };
  },
  methods: {
    say() {},
    sing() {}
  }
};
</script>

//componentB
<template>
  <div class="component-b" v-on="$listeners" v-bind="$attrs"></div>
</template>

<script>
export default {
  name: "ComponentB",
  props: {
    age: Number
  },
  mounted() {
    console.log(this.$attrs, this.$listeners);
    //{name: "六哥", tag: "帅"}, {mouseover: ƒ}
  }
};
</script>

猜你喜欢

转载自www.cnblogs.com/cjh1996/p/12812652.html