前言
我最近在学习vue源码的同时,一直在不停的造Vue轮子,目前了Button、Input两个最基础的轮子,也已经做了一些小的测试,在这个过程中,我发现,其实单纯比用组件库,完成一个简单的项目更加考验vue的基础知识呢~。
在接下来的一段时间,我会分享自己写组件过程中的一些记录和心得,以及涉及到的一些vue中的问题,如果可以的话,后期会完善遇到的问题中对应的源码部分内容,希望可以和大家交流学习呐` biubiu❤
>>>那么下面开始正文啦<<<
基础功能的实现
首先创建行的容器,用来装每一行的多个列
template内容
<div class="row">
<slot></slot>
</div>
css部分(用flex布局)
.row{
display: flex;
}
然后就是每一列,以及他们的关系的体现啦
<template>
<!-- span可以用来表示一行的几个g-col的分布比例 不对称的时候需要写-->
<!-- 添加属性 设置偏移量 -->
<div class="col" :class="[`col-${span}`,offset&&`offset-${offset}`]">
<slot></slot>
</div>
</template>
<script>
export default{
name:"GuluCol",
props:{
span:[Number,String],
offset:[Number,String]
}
}
</script>
<style lang="scss" scoped>
$bg-color: #FFFFCC;
$border-color:#99CCCC;
.col{
height: 100px;
background-color:$bg-color;
width:50%;
border:1px solid $border-color;
$class-prefix:col-;
@for $n from 1 through 24{
&.#{$class-prefix}#{$n}{
width: ($n/24)*100%;
}
};
$class-prefix:offset-;
@for $n from 1 through 24{
&.#{$class-prefix}#{$n}{
margin-left: ($n/24)*100%;
}
}
}
</style>
嘿嘿,在这里我们基本就可以实现一个简单的轮子了(如下图所示),可以自己设置每一行中的列数,以及每一列所占的比例~
Vue钩子函数实现网格之间的空隙
其实实现这个功能,最考验的还是css的功底了~然后就是会涉及到父子组件之间传值的问题
首先,如果想要在其中加空隙的话,大家首先想到的自然就是 margin来一波~ 但是其实存在一些潜在的风险
- 和我们之前设置的margin用来表示offset的情况冲突了,那么就会存在margin重叠的情况,导致不能达到预期的效果
- 其次就是用padding来表示间隙的大小啦(组件默认是:border-box)所以那就是可以的哦~
其实,这还真的可以(hhh),不过存在一点小问题,那就是最边上的元素 会和内容区 有padding的宽度,所以下面就是思考怎么解决这个常见的布局问题了~
从子元素上下手其实不容易,那么我们就从父元素下手,也就是row容器:
.row{
display: flex;
margin:0 -10px;
}
并且这里就涉及到一个问题,我们从用户那里获得gutter的值,但是怎么将值传给col呢,也就是说,那就涉及到父子组件之间的传值了
那怎么传值呢,选择在父组件的mounted函数阶段获取子组件,并且设置其gutter值为当前的gutter值
mounted(){
this.$children.gutter.forEach((vm)=>{
vm.gutter=this.gutter)
}
在子组件中的data中设置gutter变量就好,毕竟data中没有gutter值的话,父组件怎么也拿不到的嘿嘿~
如下:
data(){
return {
gutter:0
}
}//至于为什么要return 应该大家都是知道的吧,每个组件都要保持其独立性
这样就完成了中间有间隙的设置如下:
涉及到的Vue知识点
一、created和mounted的区别
- 在
created阶段,这个时候实例对象已经被创建,组件被创建好,但是还没挂载到页面上 - 在
mounted阶段,页面已经渲染完成,el被创建的实例对象给替代了(经历了编译-渲染-挂载el.append())
二、$children和$parent的使用,以及父子组件之间的生命周期执行顺序
- 其实这个问题是十分好理解的,不需要去特意记住,只要明确知道一个点
父组件存在的时候,子组件才可以挂载,子组件挂载完成之后,父组件才算挂载完成 - 结论就是:父created——>子created——>子mounted——>父mounted
- 更新过程和销毁过程都是一样的原理(其实真的非常符合人之常情,一点不抽象hhh)
总结
以上就是这个简单轮子的大概情况啦~具体代码可以参考github的vue-ui仓库啦~(还有一些简单的测试用例哒)
这个只是初步完成了功能,代码还有很多问题,会进行修改哒~如果有什么好的想法,也可以一起交流哦~
大佬忽略···
hhhh最后说一句,有21届一起毕业的小伙伴可以一起哈!
❤组件制作参考了方方的课程~大家多多关注哒