一、开始之前先创建一个分支来保存下当时的提交,别人就不需要一直翻提交记录了
image.png二、
1、先做出最基本的样式,row和colmun,在<g-row>上添加不同的属性,一般一行默认是24;
2、引用scss语法,来简化css;
- 一般写法:
//把24个长度都一一写出来太麻烦了,所以要用scss,去循环
<style>
.col[data-span='1']{
width: 4.166667%;
}
.col[data-span='2']{
width: 8.333333%;
}
.......
.col[data-span='22']{
width: 91.666667%;
}
</style>
<g-row class="row">
<g-col class="col" data-span='2'></g-col>
<g-col class="col" data-span='22'></g-col>
</g-row>
- 用scss后
<style lang="scss">
.col{
height: 100px;
width: 50%;
background-color: grey;
border: 1px solid green;
$class-prefix: col-; //定义class的前缀
@for $n from 1 through 24 { //$n就是传进来的span
&.#{$class-prefix}#{$n} {
width: ($n / 24) * 100%; //乘100%就会变成百分数
}
}
}
</style>
-
这里另外一个小知识点:
1 && 2, null || 3这种几乎不会返回true或false
image.png - offset是那一列左边需要空出多少间隔(这个传数字,所有列的span、offset加起来要为24);gutter是一行中每列之间的间隔需要空出多少像素值(gutter要传具体的像素值);
3、这里写gutter时遇到一个问题,我们的<g-col>怎么来获取到gutter的值呢,相当于就是我们怎么把这个属性值往下传给孙子?注意啦!!!我们在<g-row>里通过mounted()钩子函数来获取gutter的值,再把它传给<g-col>;
name: 'GuluRow',
props:{
gutter:{
type: [Number, String]
}
},
mounted(){
const that = this
that.$children.forEach((children)=>{
children.gutter = that.gutter
})
}
//col中用来接收gutter
data(){
return {
gutter: 0
}
}
4、重构
- 重构:通过微小的调整使你的代码变得更好(每天都要做的事情,完成一个小功能就去重构一下);
- 重写: 大调整(隔一段时间才去做);
- 什么代码需要重构?
①重复两次以上的代码,②一眼看去,看不懂的代码;
5、 如何使用gutter、justify:使用justify时,col最好不要给span值,要让它里面的内容自己撑起来;使用gutter时,要注意的是,不要直接给<g-col>一个边框,要在<g-col>里写一个<div>包住内容;
三、响应式
1、 几乎所有的UI组件都是抄袭BootStrap的,但现在很少人用BootStrap了,因为BootStrap是基于jQuery的;
2、(obj, str = '')=>{}
,意思是第二个参数str不传的话,我就自动默认为空;
3、有哪几个临界值呢?
- 576px,768px,992px,1200px,1600px(这个太大了,一般可不写)
- Mobile First 移动端优先;
-
媒体查询的css样式一定要写在下面,否则会被覆盖掉,因为后写优先级高;
image.png
4、 数组或对象前面加...
// 数组
var number = [1,2,3,4,5,6]
console.log(...number) //数组的每一个值以字符串形式返出去
//对象
var man = {name:'nn',age: 20}
console.log({...man})
打印结果.png
5、 图片想要响应式,css写{max-width: 100%;}
四、测试用例
1、如果要测试的是css属性,那么请一定要create一个div,把这个div append进body中,最后再移除这个div,如果不这样,那么你的css就无法出现在页面中;具体例子可见row.test.js中的测试;
2、done()是什么东西啊?
- 测试代码中,如果有异步操作,一定要给函数添加参数
done
,在异步操作结束的地方写上done()
;没有done(),会认为里面的操作全是同步的(这是测试框架规定的); -
setTimeout(()=>{},0)
就是异步函数,里面的内容先扔进队列,同步执行完再去执行它;
it('可以设置gutter', (done) => {
Vue.component('g-row', Row)
Vue.component('g-col', Col)
const div = document.createElement('div')
document.body.appendChild(div)
div.innerHTML = `
<g-row gutter="20">
<g-col span="12"></g-col>
<g-col span="12"></g-col>
</g-row>
`
let vm = new Vue({
el: div
})
// 上面这样写,和new Vue({}).$mount(div)是一样的
// setTimeout是异步函数,它不会等待里面的内容执行出结果
setTimeout(()=>{
const row = vm.$el.querySelector('.row')
expect(getComputedStyle(row).marginLeft).to.eq('-10px')
expect(getComputedStyle(row).marginRight).to.eq('-10px')
const cols = vm.$el.querySelectorAll('.col') //这里注意querySelectorAll
expect(getComputedStyle(cols[0]).paddingRight).to.eq('10px')
expect(getComputedStyle(cols[1]).paddingLeft).to.eq('10px')
done() //这里加上done()
vm.$el.remove()
vm.$destroy()
})
})
3、同步、异步
- 异步:我不会等函数里面的内容出结果(会把异步的东西扔进一个队列里),我会直接往下走,等同步函数执行完毕,再去执行队列里的异步函数;
- 同步:我一定会等我里面的东西全部执行完毕,才会继续往下进行;
五、布局
1、vue的options中的name的第二个作用,为了获取vm.$children
的每一项的$options.name
;第一个作用就是用Vue开发者工具查看的时候,组件会以name命名;
data(){
return {
layoutClass: {
hasSider: false
}
}
},
mounted(){
this.$children.forEach((vm)=>{
if(vm.$options.name === 'GuluSider'){
this.layoutClass.hasSider = true
}
})
}
第二个.png
第一个.png
网友评论