什么是插槽

混合父组件的内容与子组件自己的模板,弥补视图的不足。这个过程称为内容分发。
插槽,也就是slot,是组件的一块HTML模板,一个slot最核心的两个问题是显示不显示和怎样显示

组件编译的作用域

先看一段代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>插槽slot</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <my-component></my-component>
  10. {{message}}
  11. </div>
  12. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  13. <script>
  14. Vue.component('my-component', {
  15. template: '<div></div>',
  16. data() {
  17. return {
  18. message: '我是子组件message的内容'
  19. }
  20. }
  21. })
  22. let app = new Vue({
  23. el: '#app',
  24. data: {
  25. message: '我是父组件message的内容'
  26. },
  27. })
  28. </script>
  29. </body>

页面上渲染 message 的时候,出现的会是父组件 data 内容,因为整个 app 都是父组件的作用域,
如果想在子组件中使用 message,那只能在 my-component 的 template 中使用

插槽解决的问题就是在父组件中插入内容

插槽用法

单个插槽

  1. <body>
  2. <div id="app">
  3. <my-component>
  4. <p>在父组件插入的内容</p>
  5. </my-component>
  6. </div>
  7. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  8. <script>
  9. Vue.component('my-component', {
  10. template:
  11. ' <div>\n' +
  12. ' <slot>\n' +
  13. ' 默认出现的内容\n' +
  14. ' </slot>\n' +
  15. ' </div>',
  16. data() {
  17. return {
  18. message: '我是子组件message的内容'
  19. }
  20. }
  21. })
  22. let app = new Vue({
  23. el: '#app',
  24. data: {
  25. message: '我是父组件message的内容'
  26. },
  27. })
  28. </script>

具名插槽

  1. <!--html-->
  2. 具名插槽 <br>
  3. <lala-component>
  4. <h3 slot="header">标题</h3>
  5. <p>正文 1</p>
  6. <p>正文 2</p>
  7. <p slot="footer">底部信息</p>
  8. </lala-component>
  9. <script>
  10. Vue.component('lala-component', {
  11. template:
  12. ' <div>\n' +
  13. ' <div class="hearder"><slot name="header"></slot></div>\n' +
  14. ' <div class="content"><slot></slot></div>\n' +
  15. ' <div class="footer"><slot name="footer"></slot></div>\n' +
  16. ' </div>',
  17. })
  18. </script>

image.png

作用域插槽

作用域插槽是一种特殊的slot,使用一个可以复用的模板来替换已经渲染的元素
简单来说就是从子组件获取数据

  1. <!--html-->
  2. 作用域插槽 <br>
  3. <dida-component>
  4. <template slot="dida" slot-scope="prop">
  5. {{prop.text}}
  6. </template>
  7. </dida-component>
  8. <script>
  9. Vue.component('dida-component',{
  10. template:
  11. '<div>\n' +
  12. ' <slot text="我是子组件的数据" name="dida"></slot>\n' +
  13. '</div>'
  14. })
  15. </script>

访问 slot

  1. <script>
  2. mounted() {
  3. let header = this.$slots.header
  4. let text = header[0].elm.innerText
  5. let html = header[0].elm.innerHTML
  6. console.log(header);
  7. console.log(text);
  8. console.log(html);
  9. }
  10. </script>