整理一下面试官问到的一些问题
- css中position: static的用法,有没有用过
static跟fixed最大的区别应该是static没有脱离文档流?
真的没用过欸,有没有谁能告诉我啊,哭。
absolute
生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。
元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。
fixed
生成绝对定位的元素,相对于浏览器窗口进行定位。
元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。
relative
生成相对定位的元素,相对于其正常位置进行定位。
因此,"left:20" 会向元素的 LEFT 位置添加 20 像素。
static 默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。
inherit 规定应该从父元素继承 position 属性的值。
- rem和em
em:
参考物是父元素的font-size,具有继承的特点。浏览器默认字体是16px,整个页面内1em不是一个固定的值。
字体大小同样都是1.5em,但是效果却截然不同,按照W3C提供的公式,我们可以计算下: class为id1的div字体大小继承自父元素body:16px*1.5em = 24px class为id2的div字体大小继承自父元素id1:24px*1.5em = 36px class为id3的div字体大小继承自父元素id2:36px*1.5em = 54px
rem是CSS3新增的一个相对单位,但相对的只是HTML根元素。通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。
- 在移动端布局时出现边框消失该怎么办
-> 我没搞太懂,因为没遇到过,面试官点拨了一下,建议用伪元素画边框
- vw和vh
vm、vh、vmin、vmax是一种视窗单位,也是相对单位。它相对的不是父节点或者页面的根节点。而是由视窗(Viewport)大小来决定的,单位 1,代表类似于 1%。 视窗(Viewport)是你的浏览器实际显示内容的区域—,换句话说是你的不包括工具栏和按钮的网页浏览器。
vw:视窗宽度的百分比(1vw 代表视窗的宽度为 1%)
vh:视窗高度的百分比
vmin:取当前Vw和Vh中较小的那一个值
vmax:取当前Vw和Vh中较大的那一个值
- 不同平台适配分辨率的方法
-> 我就回答用过bootstrap和element-ui,其他简单的场景一般自己手写@media适配
- vue的生命周期?发送时一般会在哪个生命周期?
beforeCreate
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created
在实例创建完成后被立即调用。
在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
如果要在第一时间调用methods中的方法,或者操作data中的数据,可在此钩子中进行操作。
需要注意的是,执行此钩子时,挂载阶段还未开始,$el 属性目前不可见。
此时,可以进行数据请求,将请求回来的值赋值给data中的数据。
beforeMount
在挂载开始之前被调用,此时模板已经编译完成,只是未将生成的模板替换el对应的元素。
在此钩子函数中,可以获取到模板最初始的状态。
此时,可以拿到vm.$el,只不过为旧模板
mounted
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
在该钩子函数中的vm.$el为新模板。
执行完该钩子函数后,代表实例已经被完全创建好。
如果要在第一时间,操作页面上的dom节点时,可以在此钩子函数中操作
beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。此时数据已经更新,但是DOM还未更新
updated
数据更改导致DOM重新渲染后,会执行该钩子函数。
此时数据和dom同步。
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
可以在该钩子函数中,清除定时器。
destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除。
- vue父子组件通信
props, $emit, $attrs, $listeners, $parent, $children
感觉这样回答不是很好,应该补充上单向数据流之类的?
- 简述一下vue中的双向数据绑定是怎么实现的
v-model:
通过该指令,可以在表单元素上实现双向数据绑定
v-model本质上是语法糖,可以用简单的一个指令实现监控输入和绑定属性两个功能。
<input type="text" v-model="msg" />
<input type="text" @input="msg = $event.target.value" :value="msg" />
- 有没有用过插槽
我当时就回答只写过简单的练习,没用过复杂的,真想打死我自己...不过确实是没怎么想起来。
插槽:
现有父组件Parent.vue和子组件child.vue
父组件中使用插槽:
<child>
写上你要传递给子组件的结构,比如<p>xxxxx</p>啥的
<child/>
子组件中准备插槽模板:
<div class='这是一个子组件'>
这里有一堆其他的标签,比如<ul><li></li></ul>啥的
<slot></slot>
</div>
到了最终编译的时候,父组件会变成:
<div class='这是一个子组件'>
这里有一堆其他的标签,比如<ul><li></li></ul>啥的
写上你要传递给子组件的结构,比如<p>xxxxx</p>啥的
</div>
- websocket
没用过,面试官很亲切得讲解了一下,自己回来又查了一下:
网上就有相关介绍的文章
-> http://www.ruanyifeng.com/blog/2017/05/websocket.html
- 服务器怎么判断客户端的权限,决定是否展示内容
我就随口说(我是真的菜,脑子一片空白,愣是思考了好久才反应过来),cookie和session吧...
- vue路由被设置成history之后会怎么样?
当时没想起来...
路径中不会显示很丑的哈希符号#
种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,
当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。
所以,要在服务端增加一个覆盖所有情况的候选资源:如果 URL匹配不到任何静态资源,则应该返回同一个 index.html 页面,
这个页面就是你 app 依赖的页面。
- h5新增的内容
当初学h5这块的时候,有过前面css3的经验,应该就是基本结构没变,多了一些标签什么的,需要用的时候直接查文档应该就能上手来着,结果昨天面试就掉坑里了。我自己就只说了新增的一些语义化标签,header,section,article,video什么的,连canvas都忘了。哎。
面试的公司好像要用到svg比较多,面试官又和蔼可亲地跟我说了一些svg的问题...
/********
主要是因为‘SVG DOM 中的每个元素都是可用的,可以为某个元素附加 JavaScript 事件处理器’这个特性,如果是做工程一类的需要动态显示和控制某些指标的管理系统的话,用svg应该会比较方便。
*********/
下面简单总结一下canvas和svg吧,具体其实应该就是会用就可以,但是有总结在面试沟通的时候会方便一些吧。
canvas:
1. 本身没有绘制能力,绘图过程由js完成
2. js获取canvas元素
3. 获取context对象
4. 绘制路径
5. 填充颜色
svg:
1. SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
-> SVG 图像在放大或改变尺寸的情况下其图形质量不会有损失
-> SVG 是可伸缩的
-> SVG 图像可在任何的分辨率下被高质量地打印
-> SVG 可在图像质量不下降的情况下被放大
2. SVG 使用 XML 格式定义图形
-> SVG 图像可通过文本编辑器来创建和修改
-> SVG 图像可被搜索、索引、脚本化或压缩
-> SVG DOM 中的每个元素都是可用的,可以为某个元素附加 JavaScript 事件处理器
3. SVG 是万维网联盟的标准
其他H5特性:
- HTML5 Geolocation API 用于获得用户的地理位置。
- 拖放是 HTML5 标准的组成部分:任何元素都是可拖放的。
- 通过本地存储(Local Storage),web应用程序能够在用户浏览器中对数据进行本地的存储,优于cookie
window.localStorage - 存储没有截止日期的数据
window.sessionStorage - 针对一个 session 来存储数据(当关闭浏览器标签页时数据会丢失)
- HTML5 引入了应用程序缓存(Application Cache),这意味着可对 web 应用进行缓存,并可在没有因特网连接时进行访问
- Web worker 是运行在后台的 JavaScript,不会影响页面的性能。
由于 web worker 位于外部文件中,它们无法访问下例 JavaScript 对象:
window 对象
document 对象
parent 对象
- SSE Server-Sent 事件允许网页自动从服务器获得更新。
- 如何实现多组件之间的通信
这是面试官最后问的问题来着,前面搞忘了,补上...
我回答得不是很好,只说了vuex什么状态管理啥的,时间来不及了,我自己当时也记不清该怎么说。
Vuex是vue的状态管理工具,为了更方便的实现多个组件共享状态。
1. 安装组件
npm install vuex --save
2. 引入该库,在vue中使用
import Vuex from 'vuex';
Vue.use(Vuex);
3. 新建Store对象
const store = new Vuex.Store({
//一些配置项
state: {
/***状态***/
state: {
count: 0
}
},
getters: {
/***state的计算属性***/
doubleCount (state) {
return state.count * 2;
}
},
mutation: {
/***更改state的方法,组件要更改状态只能通过提交mutation来进行操作***/
increment (state) {
// 变更状态
state.count++
}
}
})
4. 在Vue对象中配置
new Vue({
store,
})
5. 在组件中使用
可以通过this.$store获得Store对象中的一系列配置
也可以通过辅助函数和解构赋值获取对象中的一系列属性
import { mapState, mapGetters,mapMutations } from 'vuex';
例:通过提交mutation来更改state状态,使得整个流程更加清晰,避免直接更改状态带来的误解
this.$store.commit('increment');
- Vue.nextTick()
在页面重新渲染,DOM更新后,会立刻执行vm.$nextTick
可以作为promise使用
Vue.nextTick().then(() => {
console.log(vm.$el.innerHTML);
})
- 数组有哪些方法?怎么实现数组去重?
1. 利用对象属性的唯一性
const obj = {};
const arrTest = [1, 3, 6, 6, 7, 9, 7, 10];
const arrNew = [];
for (let i = 0; i<arrTest.length; i++) {
if (obj[arrTest[i]]) {
continue;
}
obj[arrTest[i]] = 'test';
arrNew.push(arrTest[i]);
}
console.log(arrNew);
2. 利用Indexof方法
const arrTest = [1, 3, 6, 6, 7, 9, 7, 10];
const arrNew = [];
arrNew[0] = arrTest[0];
for (let i = 0; i<arrTest.length; i++) {
if (arrNew.indexOf(arrTest[i])>=0) {
continue;
}
arrNew.push(arrTest[i]);
}
console.log(arrNew);
3. 利用ES6的set
const arrTest = [1, 3, 6, 6, 7, 9, 7, 10];
const arrNew = [...new Set(arrTest)];
console.log(arrNew)
- 怎么解决ios移动端300ms点击延迟的问题
看网上的资料,有人建议用fastclik.js的
也有人说现在的浏览器,只要设置了viewport基本不会有这样的问题...