组件是为了解决复用而诞生的
创建组建
定义创建,名为todo-item的组件
<div id="app">
<ul>
<todo-item v-for="item in list" :title="item.title" :del="item.del"></todo-item>
</ul>
</div>
<script>
<!--todo-item为属性名称-->
Vue.component("todo-item",{
<!--定义一个属性声明-->
<!--定义title为String类型,del为Boolean类型,且默认值为:false-->
props:{
title:String,
del:{
type:Boolean,
default:false
}
},
<!--定义模板-->
template:
'<li>' +
' <span v-if="!del">{{title}}</span>\n' +
' <span v-else style="text-decoration: line-through">{{title}}</span>\n' +
' <button v-show="!del">删除</button>\n' +
'</li>',
data:function () {
return{}
},
methods:{
}
})
var vm = new Vue({
el:"#app",
data: {
<!--在list中定义两组数据-->
list: [
{
title: "课程-1",
del: false
},
{
title: "课程-2",
del: true
}]
}
})
</script>
效果:
另一种写法
<div id="app">
<todo-list></todo-list>
</div>
<script>
<!--todo-item为属性名称-->
Vue.component("todo-item",{
<!--定义一个属性声明-->
<!--定义title为String类型,del为Boolean类型,且默认值为:false-->
props:{
title:String,
del:{
type:Boolean,
default:false
}
},
<!--定义模板-->
template:
'<li>' +
'<span v-if![image-20200703182159167](/home/codeyuan-y/.config/Typora/typora-user-images/image-20200703182159167.png)="!del">{{title}}</span>\n' +
'<span v-else style="text-decoration: line-through">{{title}}</span>\n' +
'<button v-show="!del">删除</button>\n' +
'</li>',
data:function () {
return{}
},
methods:{
}
})
Vue.component("todo-list",{
template:
'<ul>' +
'<todo-item v-for="item in list" :title="item.title" :del="item.del"></todo-item>' +
'</ul>',
data:function () {
return{
<!--在list中定义两组数据-->
list: [{
title: "课程-1",
del: false
},
{
title: "课程-2",
del: true
}]
}
})
var vm = new Vue({
el:"#app"
})
</script>
点击事件
当点击删除时会出现相应 Hello World弹框
<!--todo-item为属性名称-->
Vue.component("todo-item",{
<!--定义一个属性声明-->
<!--定义title为String类型,del为Boolean类型,且默认值为:false-->
props:{
title:String,
del:{
type:Boolean,
default:false
}
},
<!--定义模板-->
template:'<li>' +
' <span v-if="!del">{{title}}</span>\n' +
' <span v-else style="text-decoration: line-through">{{title}}</span>\n' +
' <button v-show="!del" @click="handleClick">删除</button>\n' +
' </li>',
data:function () {
return{}
},
methods:{
handleClick(){
alert("Hello World")
}
}
})
使用子组件向父组件传值
<!--todo-item为属性名称-->
Vue.component("todo-item",{
<!--定义一个属性声明-->
<!--定义title为String类型,del为Boolean类型,且默认值为:false-->
props:{
title:String,
del: {
type: Boolean,
default: false
}
},
<!--定义模板-->
template:'<li>' +
' <span v-if="!del">{{title}}</span>\n' +
' <span v-else style="text-decoration: line-through">{{title}}</span>\n' +
' <button v-show="!del" @click="handleClick">删除</button>\n' +
' </li>',
data:function () {
return{}
},
methods:{
handleClick(){
alert("Hello World")
<!--触发父组件当中的@delete,并且将title参数传入-->
this.$emit("delete",this.title)
}
}
})
Vue.component("todo-list",{
template:
'<ul>\n' +
' <todo-item v-for="item in list" @delete="handleDelete" :title="item.title" :del="item.del"></todo-item>\n' +
'</ul>',
data:function () {
return{
<!--在list中定义两组数据-->
list: [{
title: "课程-1",
del: false
},
{
title: "课程-2",
del: true
}]
}
},
methods:{
handleDelete(val){
alert(val)
}
}
})
var vm = new Vue({
el:"#app"
}
插槽
插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。
<div id="app">
<todo-list>
<todo-item slot="first-slot" v-for="item in list" :title="item.title" :del="item.del"></todo-item>
<!--
上面这种是老版本写法:直接在标签中加slot
下面这是新版本写法:加一层template
-->
<template v-slot:second-slot>
<span>Hello World</span>
</template>
</todo-list>
</div>
<script>
<!--todo-item为属性名称-->
Vue.component("todo-item",{
<!--定义一个属性声明-->
<!--定义title为String类型,del为Boolean类型,且默认值为:false-->
props:{
title:String,
del: {
type: Boolean,
default: false
}
},
<!--定义模板-->
template:
'<li>' +
'<span v-if="!del">{{title}}</span>\n' +
'<span v-else style="text-decoration: line-through">{{title}}</span>\n' +
'<button v-show="!del">删除</button>\n' +
'</li>'
})
Vue.component("todo-list",{
<!--在模板中定义一个插槽,如果不使用name进行对应,一个插槽能显示 <todo-list>里面的所有内容-->
template:'<ul>' +
'<slot name="first-slot"></slot>'+
'<slot name="second-slot"></slot>'+
'</ul>',
})
var vm = new Vue({
el:"#app",
data:{
<!--在list中定义两组数据-->
list: [{
title: "课程-1",
del: false
},
{
title: "课程-2",
del: true
}]
}
})
</script>