这是我参与更文挑战的第 2 天,活动详情查看: 更文挑战
2021-06-02 Vue2 Vue2的组件化开发
宝刀未老,Vue2组件化开发
于总结这期知识点的时候,vue3其实已经比较成熟了,使用vue3开发项目,是真的丝滑般的顺畅~,但是在很多企业项目应用中仍然是vue2,只有少许的新项目才会采用vue3去开发,甚至很多的新项目依然采用vue2去开发,毕竟生态组件完善,所以讲vue2知识点的系列称为“宝刀未老”,但是啊技术领域就是这样,没有一直锋利的宝刀,只有一直不断的业务~,现在未老,但终会老去!有点伤感是吧!卷起来吧,少年。本系列不讲特别基础的东西,基础不行的去看vue2文档吧,我不想copy
1. Vue2中组件的传参方式
-
非边界情况
props
$emit/$on
event bus
vuex
-
边界情况
$parent
、$children
、$root
、$refs
(一般要配合$emit/$on
)provide/inject
$attrs
也就是当子组件没有声明props,而父组件有给子组件一个属性值,例如:<test-child :test="'我是子组件'"></test-child>
,那么子组件要获取这个属性值就是通过this.$attrs.test
去获取$listeners
,理解了$attrs
对应的是属性,其实$listener
对应的就是方法
这里是重点说一下重要的几个一个是event bus
一个是边界情况
1.1 event bus
也就是数据总线,其实有一个很简单的内部实现方法就是,你直接用Vue.prototype.$bus = new Vue();
,为什么可以这样创建一个总线呢?可以简单的理解成,new Vue()
就是最大的那个vue组件被实例化了,然后就拥有了$emit
和$on
这两个方法属性
一般使用如下:
// main.js
Vue.prototype.$bus = new Vue();
// 组件A在$bus 上注册一个方法
this.$bus.$emit('testEmit','我坐公交来的')
// 组件B要$bus去监听组件A注册一个方法
created(){
this.$bus.$on('testEmit',(value)=>{
console.log( value ,'接受到了')
})
}
通过上面的方式就能实现任何层级组件的一种通讯
1.2 $parent
其实用$parent实现数据通讯,和event bus
有者异曲同工之妙,因为这个是取父实例,如果当前实例有的话
例如:
// 兄弟组件A
mounted(){
this.$parent.$emit('sendMsg','我发送一个消息')
}
// 兄弟组件B
created(){
this.$parent.$on('sendMsg',(value)=>{
console.log(value,'我接受到兄弟a给我的消息了')
})
}
1.3 $root
如果理解了event bus
和$parent
其实这个也差不多,$root
充当的角色和$bus
、$parent
是差不多的,所以,在传递组件信息方面用法上区别不大
1.4 $refs
这个就$refs如果是绑定的vue组件,他就是vue的一个组件实例,就能拿到这个组件的实例就能拿到这个组件的方法,数据等等一些信息,具体的东西可以console.dir()
打印一下看看,当然如果是绑定的是一个原生dom元素,那么就是拿到就是原生的dom元素。
1.3 $children
其实这个边界用的比上面的要少很多很多。这个可以拿到组件下子组件实例的元素组成的数组,很关键的一点是$children中的子元素成员并不保证顺序
1.5 provide/inject
跨层级传参
其实这个东西也挺好用的,祖先到子元素传值变得更加简单
具体用法看下面代码:
// 祖先元素
...
data(){
return{
reactive:{
num:0
}
}
},
provide(){
return{
test:'注入',
reactive:this.reactive
}
}
...
// 子元素
...
inject:{
// 类似于props
testOne:{
from:'test',
default:{
num:0
}
},
reactive:{
from:'reactive'
}
}
...
值得注意的是provide/inject
本身是没有响应式的,那么怎么做到数据响应式变化呢,那就是provide去提供一个响应式的引用类型变量,引用类型里面的值改变,子元素inject到的这个引用数据也就响应式的,里面的值会同步改变
2. vue组件之v-model的实现
其实这部分很简单,只是因为我们通常是做业务,很少用到,
自定义组件的 v-model
步骤:
- 在自定义组件中加上model属性,指定绑定的属性和要分发的事件名称
- 然后再该组件写上model指定的属性和分发的事件并完善,这个一个组件的v-model就完成了
...
model:{
prop: 'show',
event: 'change'
},
methods: {
closeEvent(){
this.$emit('change',false)
}
}
...
3. vue的message实现思路
接下来就看一下message的实现,然后窥一斑见一豹。(最简单的方式就是参考element-ui里面的实现方式) 其实如果有想法可以先到Element官网里面看一下message的功能,这边就讲讲核心的东西
- 直接使用
this.$message[type]
,就能调用 - message节点是插入到body上面的
第一个点解决很好解决,直接使用Vue.prototype.$message = message,只需要实现message这个函数即可
第二点怎么解决了,其实也很容易,先创建一个message
的模板,然后使用Vue.extend
创建一个“子类”比如叫instanceClass
。参数是一个包含组件选项的对象,然后再使用const instance = new instanceClass.$mount()
去获取这个子类的实例,然后通过这个实例的$el
就能拿到这个实例的真实的dom元素,最后document.body.appendChild(instance.$el);
通过以上两步就完美的解决了实现message的核心步骤,其他细枝末叶就读者自己思考实现吧~