您现在的位置是:首页 >技术交流 >深入理解vue插槽网站首页技术交流

深入理解vue插槽

南风number 2024-08-14 12:01:03
简介深入理解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>
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。