先定义一个父组件todo-list,和子组件

<!-- 父组件-->
<template>
    <div>
        <ul>
            <slot>当父组件不填充内容时候,展示这行文字</slot>
        </ul>
    </div>
</template>
<script>
export default {
    name: 'todo-list'
}
</script>
<!-- 子组件-->
<template>
    <div>
        <li>
            <slot name="id-slot"></slot>
            <span v-if="!del">{{title}} </span>
            <span v-if="del" style="text-decoration: line-through">{{title}} </span>
            <slot name="time-slot"></slot>
            <slot name="scope-slot" :scopeValue="value"></slot>
            <button v-if="!del" @click="handleClick">删除</button>
        </li>
    </div>
</template>
<script>
export default {
    name: 'todo-item',
    props: {
        // 接受参数类型,默认值
        title: String,
        del: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            value: '已学习'
        }
    },
    methods: {
        handleClick() {
            // 阻止冒泡,或者在click事件上加.stop修饰符
            // e.stopPropagation()
            this.$emit('delete', this.title)
        }
    }
}
</script>

引用组件

<template>
	<div id="app">
		<todo-list class="todo-list">
      		<todo-item v-for="item in list" :key="item.id" :title="item.title" :del="item.del">
      			<!-- 这里是vue2.5以下的版本写法 -->
        		<span slot="id-slot">{{item.id}}.</span> 
        		<!-- vue2.6及以上版本 -->
		        <template v-slot:time-slot>
		          	<span>{{item.time}}</span>
		        </template>
		        <!-- 作用域插槽可以将插槽中的值拿到父级页面中 -->
		        <template v-slot:scope-slot="{scopeValue}">
		          	<span>作用域插槽:{{scopeValue}}</span>
		        </template>
      		</todo-item>
    	</todo-list>
  	</div>
</template>

<script>
import todoList from './components/TodoList.vue'
import todoItem from './components/TodoItem.vue'

export default {
  name: 'App',
  components: {
    todoList,
    todoItem
  },
  data() {
    return {
      message: 'Hello World',
      list: [
          {
              title: '课程1',
              del: false,
              id: 1,
              time: '2021-03-26'
          },
          {
              title: '课程2',
              del: true,
              id: 2,
              time: '2021-03-27'
          }
      ]
    }
  },
  methods: {
      handleDelete(){
          console.log("点击删除")
      }
  }
}
</script>
  • 插槽用作内容分发,默认可以展示组件中slot的内容,若父级传入插槽内容将其覆盖

  • 分为 匿名插槽、具名插槽和作用域插槽。

  • 匿名插槽:<slot></slot>

  • 具名插槽:在子组件中用name属性定义插槽名称,父级用slot属性调用,或者添加<template v-slot:slot-name>...</template>,在template标签里边写如要展示的内容。这是vue 2.5之前和2.6之后的两种写法。

  • 作用域插槽:在子组件插槽中定义一个属性scopeValue,在父级获取value的值

    <!-- 子组件 -->
    <slot name="item-slot" :scopeValue="value"></slot>
    <!-- 父级 -->
    <template v-slot:item-slot="{scopeValue}">
    	<span>{{scopeValue}}</span>
    </template>
    

总结:插槽传递复杂内容的方式,模版中无法传递复杂属性,用slot传递

Logo

前往低代码交流专区

更多推荐