上次以为对 Vue 的父子组件传递一清二楚了,在 6-24 的日志中写得很清楚,没想到今天同事问到的时候,我给他做演示,演示子组件如何通过自定义事件向父组件传值,结果竟然遇到了两大难题:
- 子组件在父组件后面定义,导致子组件无法正常渲染。
- 子组件通过
$emit()
方法触发父组件中的事件并传递数据,父组件如何接收数据?
第一个问题没什么值得关注的,粗心。对组件化的开发模式没有灵活掌握所致。
第二个问题,我也相当懵逼,看文档,文档中的例子着重讲了 v-on
和 $emit
如何派发和监听事件,并没有说明数据传递。专门搜索了一下才知道:既然子组件在 $emit()
方法中传递数据,那么自然,父组件也在自定义的监听响应事件中通过参数来接受数据,和异步请求的回调参数一致:
Vue.component('child', {
data () {
return {
b: 2
}
},
template: `<button @click="send">a</button>`,
methods: {
send () {
this.b++ // 可以先处理一下数据再发送
this.$emit('sendA', this.b)
}
}
})
new Vue({
template: '<div>sda<child @sendA="getA"></child></div>',
data: {a: 0},
methods: {
getA (data) { // 这里的 data 就是子组件中发送的 this.b
console.log(this.a+data)
}
}
}).$mount('#app')
在使用 nth-child
特性的时候,遇到一个问题,我使用 nth-child(2n)
来选择一组 <li></li>
元素的偶数个对象,但是实际效果却是相当混乱,问了刘哥之后,才知道,这个选择器在决定哪些元素被选中的时候,会把所有的同级元素都算入到序列之中,我的 HTML 结构中,有很多 <div></div>
结构与 <li></li>
结构并列,这样就导致效果与想象不一致。为了解决这个问题,需要用到一个新的特性,那就是 nth-of-type
选择器,这个选择器只会把固定类型的元素当做选择对象。其实,关于这些选择器的用法,我在我的这篇博客中已经写过,当时并不是在具体实战中用到,所以,忽略得一干二净,可见,学习就是要实践出真知。
另一个问题是,在前端与后端的模板渲染中,有一个常识问题,由于列表通常通过循环一次性渲染,所以,在写结构的时候,不要添加特定的样式,例如为了某个特定的效果而添加类名,更多是通过纯 CSS 来解决。
另外很容易忘记的一点是锚链接的使用方法:将超链接标记 <a>
的 href 属性设置为 #position, 在需要跳转到的位置放置一个 <a>
元素,为其设置值为 position 的 name
属性。也就是如下:
<a href="#a"></a>
<!-- 要跳转到位置 -->
<a name="a"></a>
如果要访问跨页面的锚链接,可以在链接路径后面加上 #position 就可以,例如 <a href="index.html#a">
视差滚动是常见的效果,如何做一个视差滚动呢?如果是背景不动而实现视差滚动的话,是很简单的,仅仅通过 CSS 就可以控制,一般情况下,只需要为想要保持不动的背景图像设置 background-attachment
属性为 fixed
就可以,这个属性并不常见,它用来决定一个视块背景是固定的还是相对于它的包含块滚动的,默认值为 scroll
,也就是滚动的,当设置为 fixed
的时候,就是固定的,最简单的视差效果就是这个属性引起的。
由于列表元素(<li></li>
)前面的项目符号在各大浏览器中表现不一致,所以,我们一般不使用默认的 list-style
样式,而是采用伪类来添加,可以如下:
li {
list-style: none;
content: '';
display: inline-block;
vertical-align: middle;
width: 5px;
height: 5px;
background: #666;
border-radius: 50%;
}
刚刚看 Airbnb 的 JavaScript 风格指南,里面推荐复制对象的时候,最好用 ... 扩展操作符,而不是 Object.assign() 方法,例如下面这个例子:
const obj1 = {a: 1, b: 2}
const obj2 = {c: 3, d: 4}
const obj3 = {...obj1, ...obj2}
console.log(obj3) // 输出 {a: 1, b: 2, c: 3, d: 4}
关于单行文本以及多行文本溢出省略问题,单行文本的超出问题,可以结合 text-overflow
和 white-space
两个属性来解决,例如:
p {
overflow: hidden;
text-overflow: ellipsis;
white-space: no-wrap;
}
关于多行文本溢出省略的问题,在 webkit 内核的浏览器中,可以用以下方案解决:
p {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box; /* 将对象视为弹性伸缩盒子模型 */
-webkit-line-clamp: 2; /* 显示的文本行数 */
-webkit-box-orient: vertical; /* 盒子中的子元素的排列方式 */
}
在这篇文章中提到了通过定位和伪元素来解决。基本原理是利用行高的尺寸来设置显示行的高度,然后让超出的部分 overflow: hidden
就可以。
p {
line-height: 1.5em;
height: 3em;
overflow: hidden;
position: relative;
}
/* 利用伪元素添加后面省略号 */
p::after {
content: '···';
position: absolute;
right: 0;
bottom: 0;
background-color: #fff;
}
在页面中使用锚点的时候,经常需要调整锚点的默认位置,这个时候,可以通过为锚点定义 position: relative;
之后,通过所需方向上的偏移来调整锚点的位置。这样做的好处是,它不会影响页面中其它元素的位置,因为锚点是不可见的,所以移动它的位置不会出现任何影响。例如:
a[name="link"] {
position: relative;
top: -100px; /* 向上移动 100px; */
}