天天看点

vue3 基础-slot 插槽

slot 插槽的基本认识

前几篇的内容都是父子组件通过属性传值或者事件传值这样的. 本篇来学习父组件在调用子组件时, 如果想要给子组件传递特定的内容 (dom) , 则可通过 slot 这个设计来轻易实现哦.

例如现在有这样一个场景:

组件复用

<!DOCTYPE html>
<html lang="en">

<head>
  <title>组件复用</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `
      <Son />
      <Son />
      `
    })

    app.component('Son', {
      methods: {
        handleClick () {
          alert(666)
        }
      },
      template: `
      <div>
        <input />
        <div @click="handleClick">提交</div>
      </div>
      `

    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>      

slot 初识

在父组件中, 调用了 2 次 Son 组件, 但咱希望第一次的是个 div, 第二次是个 button 的效果, 即可使用 slot 这种设计在父组件中调用子组件时给它 "增加内容":

<!DOCTYPE html>
<html lang="en">

<head>
  <title>slot</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `
      <son>
        <div>提交</div>
      </son>
      <son>
        <button>提交</button>
      </son>
    
      `
    })

    app.component('son', {
      methods: {
        handleClick () {
          alert(666)
        }
      },
      template: `
      <div>
        <input />
        <span @click="handleClick">
          <slot></slot>
        </span>
      </div>
      `

    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>      

简单来梳理这个 slot 的使用流程则是:

  • slot 的能实现父组件在调用子组件时, 直接往里面写内容 dom
  • 子组件命名要小写, 父组件在调的时候以双标签的方式往里面添加 dom
  • 子组件直接用 slot 这个双标签进行引用即可, 但其不能绑事件, 但可通过外包一层正常标签即可

slot 数据作用域

通常在组件通信中, 传递的数据是通过 data ( ) 来做驱动的, 这同样也带来了一个作用域的问题如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>slot 数据作用域</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      data () {
        return { text: '提交' }
      },
      template: `
      <son>
        <div>{{text}}</div>
      </son>
      <son>
        <button>{{text}}</button>
      </son>
    
      `
    })

    app.component('son', {
      data () {
        return { text: '点击'}
      },
      methods: {
        handleClick () {
          alert(666)
        }
      },
      template: `
      <div>
        <input />
        <span @click="handleClick">
          <slot>{{text}}</slot>
        </span>
        <div>{{text}}</div>
      </div>
      `

    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>      

父子组件都用到了 text 这个变量, 但其作用域是不同的, 我们可以看到在父组件这里, text 用的是父组件的数据.

template: `
      <son>
        <div>{{text}}</div>
      </son>
      <son>
        <button>{{text}}</button>
      </son>
    
      `
    })      

而在子组件这里, slot 里面的 text 也是用父组件数据, 但 slot 外面的 text 则用的是子组件自己的数据.

template: `
      <div>
        <input />
        <span @click="handleClick">
          <slot>{{text}}</slot>
        </span>
        <div>{{text}}</div>
      </div>
      `      

小结

最后来对本篇对 slot 的基本概念和使用做一个总结梳理如下:

  • slot 的能实现父组件在调用子组件时, 直接往里面写内容 dom
  • 子组件命名要小写, 父组件在调的时候以双标签的方式往里面添加 dom
  • 子组件直接用 slot 这个双标签进行引用即可, 但其不能绑事件, 但可通过外包一层正常标签即可
  • 父模板调用的数据属性, 用的是父模板数据属性, 子模板调用的数据属性, 用的是子莫不数据属性