4.1组件基础
组件是可复用的vue实例,带有一个名字,我们可以通过在new Vue创建的Vue根实例,把这个组件作为自定义元素来使用
4.1.1 组件注册、使用、数据传递
Vue.component(name,options)可注册组件
Vue.component('course-list',{
data(){
return {
selectedCourse:''
}
},
props:{
courses:{
type:Array,
default:()=>[]
}
},
template:`
<div>
<p v-if="courses.length==0">没有任何课程信息</p>
<ul>
<!-- class绑定 -->
<li v-for="(item,index) in courses" :key=index :class="{active:(selectedCourse===index)}" @click="selectedCourse=index">{{item}}</li>
<!--style绑定 -->
<!--<li v-for="(item,index) in courses" :key=index :style="{backgroundColor:(selectedCourse===index)?'#ddd':'transparent'}" @click="selectedCourse=index">{{item}}</li>-->
</ul>
</div>
`
})
4.1.2 自定义事件及监听
<!--监听组件事件 -->
<course-add @add-course="addCourse"></course-add>
Vue.component('course-add',{
data(){
return{
course:"",
}
},
props:['value'],
template:`
<div>
<!--表单输入绑定-->
<input v-model="course" @keydown.enter="addCourse"/>
<!--事件处理-->
<button v-on:click="addCourse">新增课程</button>
</div>
`,
methods:{
addCourse(){
this.$emit('add-course',this.course);
this.course =''
}
}
})
...
methods:{
addCourse(course){
this.courses.push(course)
}
}
...
4.1.3 在组件上使用v-model
<course-add v-model="course" @add-course="addCourse"></course-add>
Vue.component('course-add',{
//接受父组件传递的value,不需要额外维护course
props:['value'],
template:`
<div>
<!--表单输入绑定-->
<input :value="value" @input="onInput" @keydown.enter="addCourse"/>
<!--事件处理-->
<button v-on:click="addCourse">新增课程</button>
</div>
`,
methods:{
addCourse(){
// this.$emit('add-course',this.course);
//this.course =''
this.$emit('add-course')
},
onInput(e){
this.$emit('input',e.target.value)
}
}
})
v-model默认的装换是:value和@input,如果想要修改这个行为,可以通过定义model选项
Vue.component('course-add',{
model:{
prop:'value',
event:'change'
}
})
4.1.4 通过插槽分发内容
<message :show.sync="show">新增课程成功!</message>
Vue.component('message',{
props:['show'],
template:`
<div class="message-box" v-if="show">
<slot></slot>
<span class="message-box-close" @click="$emit('update:show',false)">X</span>
</div>
`
})
...
data(){
return{
show:false
}
},
methods:{
addCourse(){
if(this.course!=""){
this.show = true
}
}
}
…
如果存在多个独立内容要分发,可以使用具名插槽v-slot:name
<!--多个独立内容实现分发 -->
<message :show.sync="show">
<template v-slot:title>恭喜</template>
<template>新增课程成功!</template>
</message>
Vue.component('message',{
props:['show'],
template:`
<div class="message-box" v-if="show">
<strong><slot name="title"></slot></strong>
<slot></slot>
<span class="message-box-close" @click="$emit('update:show',false)">X</span>
</div>
`
})
4.2vue组件化的理解
定义:组件是可复用的实例,准确讲他们是VueComponent的实例,继承自Vue
优点:组件化可以增加代码的复用性、可维护性和可测试性
使用场景:什么时候使用组件?
- 通用组件:实现最基本功能,实现通用性、复用性,例如按钮组件、输入框组件、布局组件等
- 业务组件:他们完成具体业务,具有一定的复用性,例如登录组件、轮播图组件
- 页面组件:组织应用各部分独立内容,需要在不同页面组件间切换,例如列表页和详情页组件
如何使用组件
定义:Vue.component(),components选项
分类:有状态组件,function,abstract
通信:props,
e
m
i
t
(
)
/
emit()/
emit()/on(),provide/inject,
c
h
i
l
d
r
e
n
/
children/
children/parent/
r
o
o
t
/
root/
root/attrs/$listeners
内容分发:,,v-slot
使用及优化:is,keep-alive,异步组件
4.2.1 组件的本质
vue中的组件经历以下过程
组件配置=>VueComponent实例=>render()=>Virtual DOM =>DOM
组件的本质是产生虚拟DOM
详细代码地址:https://gitee.com/JingYaBei/study-vue