1. 子组件中放入插槽slot,绑定属性;
2. 在父组件里的子组件中写template,并用slot-scope获取子组件传来的数据,之后可以进行一些逻辑上的处理。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.current {
color: orange;
}
</style>
</head>
<body>
<div id="app">
<fruit-list :list="list">
<template slot-scope="slotProps">
<strong v-if="slotProps.info.id==1" class="current">{{slotProps.info.name}}</strong>
<span v-else>{{slotProps.info.name}}</span>
</template>
</fruit-list>
</div>
<script src="vue.min.js"></script>
<script>
Vue.config.devtools = true;
Vue.component('fruit-list',{
props:['list'],
template:`
<ul>
<li :key="idx" v-for="(item,idx) in list">
<slot :info='item'></slot>
</li>
</ul>
`
})
var vm = new Vue({
el:'#app',
data:{
list:[
{
id:1,
name:'apple'
},
{
id:2,
name:'orange'
},
{
id:3,
name:'banana'
}
]
}
})
</script>
</body>
</html>
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.container {
width: 250px;
margin: 100px auto;
text-align: center;
}
.title {
background-color: skyblue;
}
.list {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
}
.list input {
width: 30px;
}
.list span {
display: inline-block;
width: 30px;
height: 25px;
background-color: gray;
}
.list .del {
font-size: 24px;
color: pink;
}
.footer {
margin-top: 10px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="app">
<my-cart></my-cart>
</div>
<script src="vue.min.js"></script>
<script>
Vue.config.devtools = true;
var CartTitle = {
props:['uname'],
template:`
<h3 class="title">{{uname}}的商品</h3>
`
}
var CartList = {
props:['list'],
template:`
<div class="good-list">
<div :key='item.id' v-for='item in list' class="list">
<div>{{item.name}}</div>
<div>{{item.price}}元</div>
<div>
<span @click='sub(item.id)'>-</span>
<input type="number" :value="item.num" @blur="changeNum(item.id,$event)">
<span @click='add(item.id)'>+</span>
</div>
<div class="del" @click="del(item.id)">×</div>
</div>
</div>
`,
methods:{
del:function(id) {
this.$emit('dele-item',id);
},
changeNum:function(id,event) {
this.$emit('change-num',{
id:id,
type:'change',
num:event.target.value
});
},
sub:function(id) {
this.$emit('change-num',{
id:id,
type:'sub'
})
},
add:function(id) {
this.$emit('change-num',{
id:id,
type:'add'
})
}
}
}
var CartTotal = {
props:['list'],
template:`
<div class="footer">
总价:{{sum}}元
</div>
`,
computed:{
sum:function() {
var total = 0;
this.list.forEach(item=>{
total += item.price * item.num;
})
return total;
}
}
}
Vue.component('my-cart',{
data:function() {
return {
uname:'张三',
list:[{
id:1,
name:'文具盒',
price:10,
num:2
},
{
id:2,
name:'书包',
price:150,
num:1
},
{
id:3,
name:'钢笔',
price:200,
num:3
}]
}
},
template:`
<div class="container">
<cart-title :uname='uname'></cart-title>
<cart-list @change-num='changeNum($event)' @dele-item='delCart($event)' :list='list'></cart-list>
<cart-total :list='list'></cart-total>
</div>
`,
components: {
'cart-title':CartTitle,
'cart-list':CartList,
'cart-total':CartTotal,
},
methods: {
delCart:function(id){
var index = this.list.findIndex(item=>{
return item.id==id;
})
this.list.splice(index,1);
},
changeNum:function(val) {
if(val.type=='change') {
this.list.some(item=>{
if(item.id == val.id) {
item.num = val.num;
return true;
}
})
}else if(val.type=='sub') {
this.list.some(item=>{
if(item.id == val.id) {
item.num--;
return true;
}
})
}else {
this.list.some(item=>{
if(item.id == val.id) {
item.num++;
return true;
}
})
}
}
}
})
var vm = new Vue({
el:'#app',
data:{
}
})
</script>
</body>
</html>