slot-scope:作用域插槽特性:子组件传递数据给父组件

1. 插槽的作用:

如果没有在组件模板中放置插槽<slot>,则在html 代码中组件自定义元素之间的内容将不显示;

如果在组件模板中设置插槽<slot>,则相当于,在组件中提前预留了位置,给在html 代码中组件自定义元素之间的内容放置。即使vue 组件被封装好了不再改动,也可以在html 层面上,在自定义元素之间增加内容或者设置样式等操作。

详见:插槽的作用

例子解析:模板中添加了 <slot></slot>,是给 html 层面自定义元素 <navigation-link></navigation-link> 中间的内容 "Your Profile" 预留了显示的位置。

如果模板中没有添加<slot></slot>,在 html 层面自定义元素之间的内容将会被抛弃(深入点理解组件和html 的关系:就是html只会显示在组件模板中定义的内容。如果在 html 层面自定义元素中间插入其他内容,而没有提前在模板中定义(没有放置<slot> 作为预留位置),自定义元素中间的内容将会被抛弃,不显示。)

2. slot-scope:插槽的作用域

官网中有一句特别强调的话:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

slot-scope 是插槽 <slot> 的一个特性。使用这个特性,父组件获取子组件 slot 绑定的属性值,传递数据(通过属性值传递数据)。

组件模板: 添加 slot ,(在html 层面  <todo-list v-bind:todos="todolists" > 已将 data 里的数据 " todolists" 作为对象绑定在这个 slot 的 todos 特性(prop 属性)。)所以vue 实例里的 "todolist" 数据可以传入组件里使用,也就是组件里的 "todos"。

然后 <li> 遍历 "todos" 这个对象

Vue.component('todo-list', {
	props:{
            todos:[Array,Object]
          },
		  
//<li> 元素遍历组件porp 属性的 todos 数据(html 层面上,自定义元素已经通过 绑定porp 获取了父组件的 data元素"todolists"。也就是说,这里的 "todos" 已经获取 data元素"todolists" 的数据。这里就可以直接使用"todos" 了)
   template:`
	<ul> 
	 <li v-for="todo in todos" v-bind:key="todo.id">
	 <slot v-bind:todo="todo">
	 </slot>
	 </li>
	</ul>
`
})

vue 实例部分代码: 

new Vue({
  el: '#todo-list-example',
  data: {
    todolists: [
      {
        id: 1,
        title: 'Do the dishes',
        isComplete:true,
      },
      {
        id: 2,
        title: 'Take out the trash',
      },
      {
        id: 3,
        title: 'Mow the lawn'
      }
    ] }
})

 html 代码部分:

添加一个 <template>元素,并使用 slot-scope 特性,声明一个参数 "slotPorps", 作为插槽的作用域。

这样<template> 就可以获取 <slot>绑定的属性值("todo" 对象),达到传递并使用数据的效果。

因为 "slotPorps" 是插槽的作用域,所以 <template>使用<slot> 传过来的数据时,需要先通过  "slotPorps" 的前缀,才能拿到 <slot> 传过来的数据  {{ slotProps.todo.title }}

<div id="todo-list-example">
<!--组件 把 porp属性todos 绑定在 data数据的 "todolists",以此获取数据(子组件通过 prop 获取父组件的数据)组件获取数据后,就可以在组件内部使用了(template 里面使用)-->

<todo-list v-bind:todos="todolists" >
  <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
  <template slot-scope="slotProps">
    <!-- 为待办项自定义一个模板,-->
    <!-- 通过 `slotProps` 定制每个待办项。-->
    <span v-if="slotProps.todo.isComplete">√</span>
    {{ slotProps.todo.title }}
</span>
  </template>
</todo-list>
</div>

总结:我们已经理解了slot-scope特性,那么他有什么运用场景呢?我们可以试想一下,别人写好了一个组件,该组件已经封装好了,但他觉得,数据的显示风格让用户自己定义,就像我们上面,我们希望列表的样式由用户定义,比如我就加了一个√号。 

在组件中预留了的<slot>,即使组件封装好了,还可以让别人在 html 层面上在组件里面增加内容、设置样式(利用slot-scope传来的父组件的数据)

猜你喜欢

转载自blog.csdn.net/weixin_41796631/article/details/83279992