深入理解vue插槽

我们都知道vue的插槽及使用,一下是探究他的背后,不对的地方欢迎指正

父组件中我们在子组件中嵌套插槽,在子组件中我们使用template模板写下对应的插槽

实际上父组件中经过编译传递给子组件的插槽是函数

此图为下面示例中子组件中的输出

default是默认插槽

footer是传的动态插槽

head是传的作用域插槽

title是传的具名插槽
在这里插入图片描述
然后 我们在子组件中 通过调用 slots.xxx 即插槽的名字 返回的是对应的虚拟dom,(数据结构之所以是数组对象 因为插槽中的节点可能是多个 )
在这里插入图片描述
此时 我们调用 vue的 创建dom方法 createElementVNode

最终的效果是和 template 写出来的一样的
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
 
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>深入理解vue插槽</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
 
<body>
  <div id="app"></div>
 
  <script>
    const { createApp, createElementVNode } = Vue
    const app = createApp({
      template: `
        <parent-component></parent-component>
      `
    })
 
    app.component('parent-component', {
      setup () {
        const dynamicSlot = Vue.ref('footer')
        return { dynamicSlot }
      },
      template: `
        <div>
          <child-component :slotName="dynamicSlot">
            <template #default>
              <p>默认插槽</p>
            </template>
            <template #head="{ message }">
              <h1>作用域插槽----{{ message }}</h1>
            </template>
            <template #title>
              <p>具名插槽</p>
            </template>
            <template #[dynamicSlot]>
              <p>动态插槽</p>
            </template>
          </child-component>
        </div>
      `
    })
 
    app.component('child-component', {
      props:{
        slotName:{
          type:String
        }
      },
      setup (props, { slots }) {
        console.log(slots, 'slots--',props)
        const _default = slots.default()
        const head = slots.head({ message: '你好' })
        const title = slots.title()
        const propslotName = slots[props.slotName]()
        console.log(_default,head,title,propslotName)
        return () => {
          return createElementVNode('div', null, [
            ..._default, ...head, ...title, ...propslotName
          ])
        }
 
      },
      /* template: `
        <div>
 
          <slot></slot>
 
          <slot name="head" :message="'你好'"></slot>
 
          <slot name="title"></slot>
 
          <slot :name="slotName"></slot>
        </div>
      ` */
    })
 
    app.mount('#app')
  </script>
 
</body>
 
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值