美文网首页VUE
Vue.js slot插槽

Vue.js slot插槽

作者: OrochiZ | 来源:发表于2019-08-19 23:45 被阅读6次
    1.个人理解的插槽

    之所以使用组件,就是因为组件可以将复杂的页面分割成多个部分,每个 部分就是一个组件(也是一个vue文件)。要使用这个组件,只需要引入组件文件,并在模版中写入组件标签即可,引入了这个子组件,就相当于引入了这个组件的html模版,例如:

    // App.vue
    <template>
        <div id="app">
            <Hello />
        </div>
    </template>
    
    // Hello组件
    <template>
        <div id="hello">
            <h2>我是Hello组件</h2>
        </div>
    </template>
    

    渲染之后就是

    <div id="app">
       <div id="hello">
          <h2>我是Hello组件</h2>
       </div>
    </div>
    

    父组件想要插入数据到子组件中,无非就是将数据通过属性绑定的形式,然后子组件通过props接收

    // App.vue
    <template>
      <div id="app">
        <!-- content=我是app组件传递的数据 -->
        <Hello :content="content" />
      </div>
    </template>
    
    // Hello组件
    <template>
        <div id="hello">
            <h2>我是Hello组件 {{content}}</h2>
        </div>
    </template>
    
    <script>
    export default {
      props:['content']
    }
    </script>
    

    渲染结果

    <h2>我是Hello组件 我是app组件传递的数据</h2>
    

    通过上面例子,父组件可以通过props的形式传递数据给子组件,但是这种方法只能影响子组件的数据展示,无法对子组件的html模版结构产生影响,如果你想在父组件中插入一段html给子组件,显然无法做到,slot就是 为此而生的

    2.slot基本用法

    在原生的html中,我们经常在一个块级标签中插入n个标签,Vue中父组件给子组件插入标签也是这种写法

    // App.vue
    <template>
      <div id="app">
        <Hello>
          <!-- 在子组件中插入标签 -->
          <h2>我是插入的h2</h2>
        </Hello>
      </div>
    </template>
    

    然后在子组件中接收这个标签,子组件使用slot标签接收插入的标签,插入的标签会替换这个slot标签(slot标签的位置就是插入标签的位置)

    // 子组件
    <template>
        <div id="hello">
            <slot></slot>
            <h2>我是Hello组件</h2>
        </div>
    </template>
    

    渲染结果:

    <div id="app">
        <div id="hello">
            <h2>我是插入的h2</h2>
            <h2>我是Hello组件</h2> 
        </div>
    </div>
    

    这种插槽被称为匿名插槽,但是只能有一个(多个的话逻辑就有问题,因为不知道该由哪个插槽来替换所插入的标签元素)

    2.具名插槽

    如果有多个插槽,就需要为每个插槽添加一个标识,即name属性,方便对号入座

    <template>
        <div id="hello">
            <slot name="top"></slot>
            <h2>我是Hello组件</h2>
            <slot name="bottom"></slot>
        </div>
    </template>
    

    父组件插入标签元素时 设定slot属性 来关联对应的插槽

    <template>
      <div id="app">
        <Hello>
          <!-- 在子组件中插入标签 -->
          <h2 slot="top">我是插入的h2</h2>
          <h5 slot="bottom">我是插入的h5</h5>
        </Hello>
      </div>
    </template>
    

    插槽可以空着不用,父组件不插入标签元素,插槽就不会被渲染,利用这个特性可以控制子组件的某些空间是否展示对应的元素
    插槽和props传参可以同时使用,对于必须要展示的标签可以props传参,选择性展示的标签可以使用插槽

    3.插槽的默认内容

    slot标签内可以写html代码,如果这个插槽没有被替换,会显示该插槽内的html内容,反之会被替换

    <template>
        <div id="hello">
            <slot name="top">
              <p>我是top插槽没使用的时候展示的内容</p>
            </slot>
            <h2>我是Hello组件</h2>
            <slot name="bottom"></slot>
        </div>
    </template>
    
    // App.vue
    <template>
      <div id="app">
        <Hello>
          <h5 slot="bottom">我是插入的h5</h5>
        </Hello>
      </div>
    </template>
    

    渲染结果

    <div id="app">
        <div id="hello">
            <p>我是top插槽没使用的时候展示的内容</p> 
            <h2>我是Hello组件</h2>
            <h5>我是插入的h5</h5>
        </div>
    </div>
    
    4.slot-scope(作用域插槽) 为slot绑定数据

    子组件传递给父组件的数据,子组件通过属性绑定,将相应的数据绑定到slot标签中,当父组件要使用这个slot时,就可以读取这个数据

    // 子组件
    <template>
        <div id="hello">
            <slot name="top" :list="list">
            </slot>
            <h2>我是Hello组件</h2>
            <slot name="bottom"></slot>
        </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          list: [
            {
              name: '乔治',
              age: 4
            },
            {
              name: '佩琪',
              age: 8
            }
          ]
        }
      }
    }
    </script>
    

    父组件在替代slot的标签中添加 slot-scope属性,表示接受当前slot绑定的数据。slot-scope的值可以随意写,例如slot-scope="xxx"

    // App.vue
    <template>
      <div id="app">
        <Hello>
          <template slot-scope="xxx" slot="top">
            <p>{{xxx.list[0].name}}</p>
            <p>{{xxx.list[0].age}}岁</p>
          </template>
          <h5 slot="bottom">我是插入的h5</h5>
        </Hello>
      </div>
    </template>
    
    slot-scope.png

    传递的数据是包裹在对象内的,这样就可以接收多个数据。比如子组件的slot传递2个数据list和msg,接收的时候要使用xxx.list访问list,xxx.msg访问msg。获取了数据,就随你怎么使用了。

    // 子组件
    <slot name="top" :list="list" :msg="msg">
    
    // 父组件
    <template slot-scope="xxx" slot="top">
        <p>{{xxx.list[0].name}}</p>
        <p>{{xxx.list[0].age}}岁</p>
        <p>{{xxx.msg}}</p>
    </template>
    

    相关文章

      网友评论

        本文标题:Vue.js slot插槽

        本文链接:https://www.haomeiwen.com/subject/mjmysctx.html