组件化开发
- 概念:将一个完整的页面抽离成一个个独立的组件,最终通过一个个独立组件完成整个页面的功能
- 优势:复用
- 组件是可复用的Vue实例
组件的基本使用
组件的注册
- 全局注册:在所有的vue实例中都可以使用
- 局部注册:在所有当前实例中可以使用
注册全局组件
/**
*第一个参数:组件名
*第二个参数:是一个配置对象,该配置对象与Vue实例的配置对象几乎完全相同,
*也就是说:vue实例中用到的配置项和组件中的配置项几乎相同
*/
Vue.component('hello',{
template:`<h1 class='red'>这是hello组件</h1>`
})
注册局部组件
- 局部组件只能在当前父组件的模板中使用
- 不能在其他子组件中显示
- 示例:
components:{
/**
*child表示组件名称
*值为配置对象,与Vue.component中的第二个参数相同
*注意:子组件child属于Vue实例 因此 只能在Vue实例的模板中使用
*/
child:{
template:`<div>这是局部组件</div>`
}
}
注意点
- 注册全局组件是在到vm实例之前
- 模板只有一个根节点
- 组件的配置项和vue实例的配置项一样(如:data、methods、filters、watch、computed、钩子函数等)
- 组件的data是一个函数,返回一个对象
let Component = function(){}
// 使用对象
Component.prototype.data = {
demo:123
}
// 使用函数
Component.prototype.data = function(){
return {
demo: 111
}
}
let component1 = new Component()
let component2 = new Component()
component1.data().demo = '8888'
console.log(component2.data().demo) //456
示例
<h1 @click='fn' class='red'>这是hello组件</h1>
methods: {
fn(){
console.log('fn')
}
},
computed: {},
watch: {},
filters: {}
组件通讯
- 组件是一个独立、封闭的个体
- 组件中的数据默认情况下只能在组件内部使用,无法直接在组件外部使用
- 可以将vue实例看做一个组件
- 对于组件之间需要相互使用彼此的情况应该使用组件通讯机制来解决
- 组件通讯三种情况:
父组件将数据传递给子组件(父 => 子
1.1将要传递的数据,通过属性传递给子组件
<child :msg='pmsg'></child>
1.2.子组件通过props配置项来指定要接收的数据
props:['msg']
子组件将数据传递给父组件(子 => 父)
2.1.父组件中提供一个方法
pfn(arg){
console.log('父组件中接受到子组件传递过来的数据:',arg)
}
2.2.将这个方法传递给子组件
// 自定义事件
<child @fn='pfn'></child>
2.3.子组件调用这个方法(触发父组件中传递过来的自定义事件)
handleClick(){
// 调用父组件中的方法 fn
// 通过$emit方法来触发事件fn
// 第一个参数:表示要触发的自定义事件名称,也就是@fn
// 第二个参数:表示要传递给父组件的数据
this.$emit('fn','child msg')
}
非父子组件之间的数据传递(兄弟组件)
- 通过
事件总线(event bus)的机制
来实现 - 事件总线:实际上就是一个
空Vue实例
- 可以实现任意两个组件之间的通讯,而不管两个组件到底有什么样的层级关系
- 示例:
// 第一步:事件总线
let bus = new Vue()
// 第二步:发送数据 可在点击时间里出发事件
// 参数1: 唯一标识
// 参数2: 参数
bus.$emit('todo','what are you doing now?')
// 第三步:接收数据 可在created里注册事件
bus.$on('todo',arg => {
console.log('接收过来的',arg)
})
获取组件(或元素) - refs
- 说明:
vm.$refs
一个对象,持有已注册过ref的所有子组件(HTML元素) - 使用:
- 注册
//标签
<div ref='div'>hhh</div>
//组件
<child red='child'></child>
- js中使用
//在mounted操作DOM
this.$refs.div
this.$refs.child
- tips:如果获取的是一个子组件,那么通过ref就能获取到子组件中的`data`和`methods`
this.$refs.div
this.$refs.child
- 场景:一般在第三方的组件中,可能会用到这个功能
- 示例:
<div ref='div'>hhhhh</div>
<child ref='child'></child>
mounted(){
console.log(this.$refs.div)
console.log(this.$refs.child.fn)
}