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>
实现的效果:
但如果想要对其中的一个数据做出一些变化,比如第三个数据让它显示为红色?那该怎么办?
匿名插槽??他不行,他只是在本组件的html结构基础上的其中一个位置中加入新的html结构:
具名插槽??他也不行,他只是在本组件的html结构基础上的特定几个位置中加入新的html结构:
另外,还有一件事需要明确一下:
这里模板字符串里面的标签虽然是写在子组件中的,但是实际在浏览器中渲染出来:
,,
却是在父组件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>