vue组件再封装属性和事件的透传

1,467 阅读1分钟

今天想用vue3 做一个封装一个组件,做一个组件透传,vue2使用的是$listeners接收父组件的事件,在vue3不好使,查看文档才知道取消了。

vue3,把事件和属性都放在attrs里面,如果被封装的组件是根组件,就会直接透传下去,如果不是根组件,使用von="attrs里面,如果被封装的组件是根组件,就会直接透传下去,如果不是根组件,使用v-on="attrs",就可以把属性和事件都透传下去,不想透传的事件,可以使用emits["eventName"],意思是eventName要在当前组件消费掉。不想透传的属性可以使用props["attrName"],意思是attrName的属性在当前组件消费掉

在vue2的时候事件需要v-on="listeners",属性需要v-bind="\attrs",其他规则和vue3一样

父组件

<script setup>
import testOptionApi from './components/child.vue'

function handleMoveLeft(){
  console.log("move left")
}
function handleMoveRight(){
  console.log("move right")
}
</script>

<template>
  <header>
      <childComponent @onLeft="handleMoveLeft" @onRight="handleMoveRight"  msg="You did it!" />
      
    </div>
  </header>

</template>

<style scoped>
header {
  line-height: 1.5;
}

.logo {
  display: block;
  margin: 0 auto 2rem;
}

@media (min-width: 1024px) {
  header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }

  .logo {
    margin: 0 2rem 0 0;
  }

  header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
  }
}
</style>

子组件 ./components/t.vue


<template>
    <!-- <el-button @click="handleClickLeft" type="primary">left</el-button>
    <el-button  @click="handleClickRight" type="primary">right</el-button> -->
    <div>
      <transparentTrans v-bind="$attrs"/>
    </div>
      <el-button @click="handleClick">parent btn</el-button>
</template>

<script>
import transparentTrans from "./transparentTrans.vue"
export default {
  // inheritAttrs: false,
  emits:["onLeft"], 
  components:{
    transparentTrans
  },
  methods:{
    handleClick(){
      this.$emit("onLeft")
    }
  }
}

</script>

<style scoped>
h1 {
  font-weight: 500;
  font-size: 2.6rem;
  top: -10px;
}

h3 {
  font-size: 1.2rem;
}

.greetings h1,
.greetings h3 {
  text-align: center;
}

@media (min-width: 1024px) {
  .greetings h1,
  .greetings h3 {
    text-align: left;
  }
}
</style>

孙组件 ./components/transparentTrans.vue


<template>
    <el-button @click="handleClickLeft" type="primary">child left</el-button>
    <el-button  @click="handleClickRight" type="primary">child right</el-button>
</template>

<script>
export default {
  props:["msg"],
  methods:{
    handleClickLeft(){
      this.$emit("onLeft")
    },
    handleClickRight(){
      this.$emit("onRight")

    }
  }
}

</script>

<style scoped>
h1 {
  font-weight: 500;
  font-size: 2.6rem;
  top: -10px;
}

h3 {
  font-size: 1.2rem;
}

.greetings h1,
.greetings h3 {
  text-align: center;
}

@media (min-width: 1024px) {
  .greetings h1,
  .greetings h3 {
    text-align: left;
  }
}
</style>

上面的代码是把属性从父组件传到孙孙组件,在做一些组件再封装的时候很有用