对作用域插槽的理解:slot-scope

一,先来看看普通的组件

DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>title>
		<link rel="stylesheet" type="text/css" href="css/base.css"/>
		<style type="text/css">
			#app{
				width: 20%;
				margin: 200px auto;
				border: 1px solid #ccc;
				line-height: 30px;
				padding: 20px;
			}
		style>
	head>
	<body>
		<div id="app">
			<fruit-list :sonlist="list">
				
			fruit-list>
		div>
		
		<script type="text/javascript" src="js/vue.min.js">script>
		<script type="text/javascript">
		//子组件
			Vue.component('fruit-list',{
				props:['sonlist'],
				template:`
					
  • {{item.name}}
  • `
    }) //父组件 var vm= new Vue({ el:'#app', data:{ list:[{ id:1, name:'apple' }, { id:2, name:'orange' }, { id:3, name:'banana' }] } })
    script> body> html>

    实现的效果:
    对作用域插槽的理解:slot-scope_第1张图片
    但如果想要对其中的一个数据做出一些变化,比如第三个数据让它显示为红色?那该怎么办?
    匿名插槽??他不行,他只是在本组件的html结构基础上的其中一个位置中加入新的html结构:
    对作用域插槽的理解:slot-scope_第2张图片
    具名插槽??他也不行,他只是在本组件的html结构基础上的特定几个位置中加入新的html结构:
    对作用域插槽的理解:slot-scope_第3张图片

    另外,还有一件事需要明确一下:
    对作用域插槽的理解:slot-scope_第4张图片
    这里模板字符串里面的标签虽然是写在子组件中的,但是实际在浏览器中渲染出来:
    ,,对作用域插槽的理解:slot-scope_第5张图片
    却是在父组件app下的,也就是说想要让第三个数据变成红色(不考虑之前学过的css样式的知识哈!),就需要让父组件知道,哪个是第三个组件,于是引入了作用域插槽,它可以把子组件的数据通过slot-scope再传递给父组件,然后在父组件中直接书写html结构:

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>title>
    		<link rel="stylesheet" type="text/css" href="css/base.css"/>
    		<style type="text/css">
    			#app{
    				width: 20%;
    				margin: 200px auto;
    				border: 1px solid #ccc;
    				line-height: 30px;
    				padding: 20px;
    			}
    		style>
    	head>
    	<body>
    		<div id="app">
    			<fruit-list :sonlist="list">
    				<template slot-scope='slotprops'>
    					 
    					 
    					<strong v-if='slotprops.info.id==3' style="color: red;">{{slotprops.info.name}}strong>
    					<span v-else>{{slotprops.info.name}}span>
    				template>
    			fruit-list>
    		div>
    		
    		<script type="text/javascript" src="js/vue.min.js">script>
    		<script type="text/javascript">
    			Vue.component('fruit-list',{
    				props:['sonlist'],
    				template:`
    					
  • `
    //利用属性绑定,将每一个item转化为info,传递给父组件 }) var vm= new Vue({ el:'#app', data:{ list:[{ id:1, name:'apple' }, { id:2, name:'orange' }, { id:3, name:'banana' }] } })
    script> body> html>

    二,作用域插槽的使用方法

    第一步:父组件通过子组件标签属性绑定传递了list数组给子组件
    第二步:子组件通过propos接收了父组件传递过来的数据
    第三步:子组件拿到数组后,使用v-for渲染列表,并通过slot :info='item’的方式,把数据同样通过属性绑定的方式(渲染出来后就到父组件那边去了),把数组中的每一个对象都传递给父组件。
    第四步:父组件通过template slot-scope=‘slotprops’>

    这样一来,list数组就经历了以下几个步骤:
    1,父组件传递list数组给子组件
    2,子组件接收list数组,用v-for取出里面的每一个对象后,又传递给父组件。
    3,父组件接收每一个对象,并存储在slotprops对象中。

    三,一个疑惑

    既然数据在父组件中,为啥要传给子组件,又要子组件传回来。不麻烦吗?不是有病吗???
    这是因为,列表的渲染是需要子组件利用v-for进行的!所以子组件需要获取数据。
    而父组件中插槽位置处添加的html结构,又需要使用到对应的信息,所以数据又得从子组件处传递回来。
    那为什么不直接使用父组件中的数据呢?
    当然是可以的,但这样一来,组件化开发不复存在,只是很机械地使用父组件的数据写html结构罢了。

    四,一个简单的案例

    网上也有人说,作用域插槽是带数据的插槽。也可以这么理解,而且这个数据来源于子组件的模板字符串通过属性绑定携带过来的,也就是说,作用域插槽,子组件的模板字符串属性绑定来控制传递过来的数据,而父组件的插槽内容则是控制显示的html内容。
    子组件的模板字符串属性绑定来控制传递过来的数据:

    Vue.component('fruit-list',{
    	props:['sonlist'],
    		template:`
    			<div>
    				<li :key='item.id' v-for='item in sonlist'>
    					<slot :info='item'></slot>
    				</li>
    			</div>
    		`
    		//利用属性绑定,将每一个item转化为info,传递给父组件
    		})
    

    父组件的插槽内容则是控制显示的html内容:

    <fruit-list :sonlist="list">
    	<template slot-scope='slotprops'>
    			 
    			 
    			<strong v-if='slotprops.info.id==3' style="color: red;">{{slotprops.info.name}}strong>
    			<span v-else>{{slotprops.info.name}}span>
    		template>
    	fruit-list>
    

    举个简单的示例:

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>title>
    		<link rel="stylesheet" type="text/css" href="css/base.css"/>
    		<style type="text/css">
    			#app{
    				width: 20%;
    				margin: 200px auto;
    				border: 1px solid #ccc;
    				line-height: 30px;
    				padding: 20px;
    			}
    		style>
    	head>
    	<body>
    		<div id="app">
    			<testone :sonlist="list">
    				<template slot-scope="fatherObject">
    					<span>{{fatherObject.info.name}}span>
    				template>
    			testone>
    			
    			<hr>
    			
    			<testone :sonlist="list">
    				<template slot-scope="fatherObject">
    					<span>{{fatherObject.info.id}}span>
    				template>
    			testone>
    		div>
    		
    		<script type="text/javascript" src="js/vue.min.js">script>
    		<script type="text/javascript">
    			Vue.component('testone',{
    				props:['sonlist'],
    				template:`
    					
  • `
    //利用属性绑定,将每一个item转化为info,传递给父组件 }) var vm= new Vue({ el:'#app', data:{ list:[{ id:1, name:'apple' }, { id:2, name:'orange' }, { id:3, name:'banana' }] } })
    script> body> html>

    这里利用作用域插槽。使用同一个子组件,可以写出不同的东西:
    对作用域插槽的理解:slot-scope_第6张图片

    你可能感兴趣的:(#,vue基础,vue.js,html5,html)