什么?!插槽内的组件竟然可以被获取并修改

83 阅读1分钟

众所周知,父组件是不能直接获取子组件的插槽里面的组件 ref ,因为插槽里面的组件并不会绑定在$refs里面,并且插槽的内容是在父组件的模板中渲染的,而不是在子组件内部。

所以只能通过插槽组件在 mounted 生命周期阶段,抛出一个emit事件,然后在这个抛出的事件的实现方法里面去获取当前的 $refs.插槽组件即可。

  • 父组件:
<template>
    <ChildComponent>
        <SlotComponent ref="slotComponent" @getSlotRef="getSlotRef"></SlotComponent>
    </ChildComponent> 
</template>
<script>
export default {
    name:"ParentComponent",
    components: { ChildComponent },
    methods: {
        getSlotRef(){
            if(this.$refs.slotComponent){
                //获取到当前插槽组件 ref ,并进行操作
            }
        }
    }
}
</script>
  • 子组件
<template>
    <div>
        <slot></slot>
    </div>
</template>
<script>
export default {
    name:'ChildComponent'
}
  • 插槽组件
<template>
    <div>hello</div>
</template>
<script>
export default {
    name:'SlotComponent',
    mounted(){
        this.$emit('getSlotRef')
    }
}

在父组件不能变的情况下,如何去修改插槽组件的内容

使用场景:组件库中的组件不能修改,但想修改里面的组件实现

实现步骤:

  • 继承父组件
  • 重写父组件方法
  • 抛出事件
<template>
    <ParentComponentExpand ref="parentRef" @getSlotComponentEvent="getSlotComponentEvent" />
</template>
<script>
import { defineComponent } from 'vue';
import ParentComponent from 'ParentComponent.vue'

const ParentComponentExpand = defineComponent({
  extends: ParentComponent,
  methods: {
      getSlotRef(){
          if(this.$refs.slotComponent){
                //获取到当前插槽组件 ref ,并通过事件将 ref 抛出到父组件
                this.$emit("getSlotComponentEvent",this.$refs.slotComponent)
          }
      }
  }
})

export default {
  components: { ParentComponentExpand },
  methods:{
      getSlotComponentEvent(soltRef){
          // 获取插槽组件 soltRef 进行操作
      }
  }
}