--小编第一家面试的公司是一家刚建俩年的创业型公司(洞幺),经历过四轮面试很可惜没有被面试上,现在将面试题整理出来。
一、关于vue
1、父组件与子组件传值?
答:
1.1 父传子:父组件通过v-bind在子组件上绑定数据(数据在data里面定义好了的),子组件通过props自定义属性来接受父组件传过来的值。props属性是单向绑定,可以指定验证要求(那就props必须是对象);子组件还可以通过$parent来接受父组件传过来的值。
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:message="parentMsg"></child>
</div>
</div>
<script>
// 注册
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 "this.message" 这样使用
template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
el: '#app',
data: {
parentMsg: '父组件内容'
}
})
</script>
1.2 子传父:子组件不能直接修改父组件传过来的值,所以通过$emit()发送事件数据给父组件,父组件通过v-on来监听子组件传过来的事件数据进行相对应的操作
<div id="app">
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</div>
<script>
Vue.component('button-counter', {
template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
incrementHandler: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
</script>
ps:非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。
公共文件:bus.js
//bus.js
import Vue from 'vue'
export default new Vue()
组件A:
<template>
<div>
A组件:
<span>{{elementValue}}</span>
<input type="button" value="点击触发" @click="elementByValue">
</div>
</template>
<script>
// 引入公共的bug,来做为中间传达的工具
import Bus from './bus.js'
export default {
data () {
return {
elementValue: 4
}
},
methods: {
elementByValue: function () {
Bus.$emit('val', this.elementValue)
}
}
}
</script>
组件B:
<template>
<div>
B组件:
<input type="button" value="点击触发" @click="getData">
<span>{{name}}</span>
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
name: 0
}
},
mounted: function () {
var vm = this
// 用$on事件来接收参数
Bus.$on('val', (data) => {
console.log(data)
vm.name = data
})
},
methods: {
getData: function () {
this.name++
}
}
}
</script>
2、组件缓存用什么标签?
答:
2.1 组件缓存用:<keep-alive>标签(用来包裹动态组件)。主要用于保留组件状态或避免重新渲染。
2.2 属性:
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。(一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。)
2.3 用法:<keep-alive>包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
主要用于保留组件状态或避免重新渲染。
<!-- 基本 -->
<keep-alive>
<component :is="view"></component>
</keep-alive>
<!-- 多个条件判断的子组件 -->
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>
<!-- 和 `<transition>` 一起使用 -->
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>
注意:<keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。
3、v-if和v-show的区别?
答:
3.1 都是用于通过条件显示隐藏组件。
3.2 区别 : v-if在条件切换时,会对标签进行适当的创建和销毁。而v-show则仅在初始化时加载一次,因此v-if的开销相对来说会比v-show大。
v-if是惰性的,只有当条件为真时才会真正渲染标签,而v-show则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的CSS切换。
3.3 什么时候用v-if?
当我不需要频繁的显示元素时,用v-if;需要频繁的显示元素,则用v-show,性能高些。
4、vue中如何解决页面不重新渲染问题?
答:
4.1 : 修改对象属性后页面未重新渲染可以使用 this.$set(对象名称, '属性名', '属性值')(向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。)
--修改对象的某一属性
<template>
<div>
<div v-for='item in list'>{{item}}</div>
<button @click='click'>改变</button>
<button @click='hadelClick'>解决方法</button>
</div>
</template>
<script>
export default({
data(){
return{
list:{a:'a',b:'b'},
}
},
methods: {
click() {
// 未声明不触发渲染
this.list.c='c'
},
hadelClick(){
// 解决方法,使用vue提供的$set方法来触发渲染
this.$set(this.list,'d','d')
}
}
})
</script>
4.2 : 使用this.$forceUpdate()实例方法(强制刷新)可重新渲染页面.(迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。)
你页面不刷新但你的数据缺实修改了,可以使用this.$forceUpdate()方法 (强制刷新)
<template>
<div>
<div v-for='item in list'>{{item.a}}</div>
<button @click='click'>改变</button>
<button @click='hadelClick'>解决方法</button>
</div>
</template>
<script>
export default({
data(){
return{
list:[{a:'vue'},{a:'react'},{a:'js'}],
}
},
methods: {
click() {
this.list[0] = {a:'css'} //页面不渲染
console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
},
hadelClick(){
this.list[0] = {a:'css'} //页面不渲染
console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
this.$forceUpdate();//强制刷新
}
}
})
</script>
5、如何让css只在当前组件起作用?
答:
5.1 : 当前组件<style>写成<style scoped>
scoped三条渲染规则:
1、给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性
2、在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-2311c06a])来私有化样式
3、如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性
实例:
//实际上的
<template>
<div class="button-warp">
<button class="button">text</button>
</div>
</template>
...
<style scoped>
.button-warp{
display:inline-block;
}
.button{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
</style>
渲染后的HTML
<div data-v-2311c06a class="button-warp">
<button data-v-2311c06a class="button">text</button>
</div>
渲染后的css
.button-warp[data-v-2311c06a]{
display:inline-block;
}
.button[data-v-2311c06a]{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
注意:scoped的这一操作,虽然达到了组件样式模块化的目的,但是会造成一种后果:每个样式的权重加重了:理论上我们要去修改这个样式,需要更高的权重去覆盖这个样式。这是增加复杂度的其中一个维度。
6、vue-router 路由模式有几种?
答:有3种
1、hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;
2、history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式
3、abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式.
7、vue的俩个核心?
答:数据驱动和组件系统
数据驱动:数据的双向绑定。数据发生变化后,会重新对页面渲染,这就是Vue响应式
组件系统:组件相互构成的系统
组件的核心选项:
1 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。
2 初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。
3 接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。
4 方法(methods):对数据的改动操作一般都在组件的方法内进行。
5 生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。
6 私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。
7、promise是什么?有什么用?
二、css面试题
1、css样式覆盖规则?
答:
规则一:由于继承而发生样式冲突时,最近祖先获胜。
<html>
<head>
<title>rule 1</title>
<style>
body {color:black;}
p {color:blue;}
</style>
</head>
<body>
<p>welcome to <strong>gaodayue的网络日志</strong></p>
</body>
</html>
注意:strong分别从body和p中继承了color属性,但是由于p在继承树上离strong更近,因此strong中的文字最终继承p的蓝色
规则二:继承的样式和直接指定的样式冲突时,直接指定的样式获胜。
接着在以上案例,指定给元素加上此样式
strong {color:red;}
注意:那么根据规则二,strong中的文字最终显示为红色。
规则三:直接指定的样式发生冲突时,样式权值高者获胜。
样式的权值取决于样式的选择器:内联样式的权值1000>>ID选择器100>>类选择器10>>标签选择器1,除此以外,后代选择器的权值为每项权值之和
规则四:样式权值相同时,后者获胜。
<p class="byline">Written by
<a class="email" href="mailto:jean@cosmofarmer. com">
Jean Graine de Pomme
</a>
</p>
.byline a {color:red;}
p .email {color:blue;}
注意:“.byline a”与”p .email”都直接指定了上面的a元素,且权值都为11,根据规则四,最终显示蓝色。
规则五:!important的样式属性不被覆盖
!important可以看做是万不得已的时候,打破上述四个规则的”金手指”。
大多数情况下都可以通过其他方式来控制样式的覆盖,不能滥用!important。
2、px、em、rem的区别?
答:
px:是像素,即相对于当前显示器屏幕分辨率而言的相对长度单位。
特点:1、ie无法调整哪些使用px为单位的字体大小;
2、国外大部分网站能够调整的原因在于使用了em和rem作为字体单位;
3、火狐能够调整px、em、rem,但是大部分的中国网民都是使用的IE浏览器和内核。
em:是相对于当前对象内的文本尺寸而言的相对长度单位。
特点:1、em的值不是固定的;
2、em会继承父级元素的字体大小;
3、任意浏览器的默认字体都是16px,且未做调整的浏览器都是1em=16px。
4、为了简化em的运算,需要在body里面设置font-size=62.5%,使得1em=10px,便于运算。
rem:css3新增的相对长度单位。相对于HTML根元素。
特点:1、除了IE8以下的ie版本,其他浏览器都兼容。
注意:
1、根据你的项目来选择相对应的字体单位,如果你的用户群都使用最新版的浏览器,那推荐使用rem,如果要考虑兼容性,那就使用px,或者也可两者同时使用。
2、只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可
3、对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备。
三、js面试题
1、undefined和null的区别?
答:
undefined:是所有没有赋值变量的默认值,自动赋值;
特点:1、可以设置变量值为undefined用来清空变量
2、类型是undefined
null:主动释放一个变量引用的对象。表示一个变量不再指向任何对象地址。即该变量变为一个空对象。
特点:1、可以设置用来清空对象。
2、类型是object
3、使用:当使用一个大的对象,需要对其释放内存的时候,可以设置为null。
区别:
相同:都是原始类型,
不同:1、定义不同
2、值相等,但类型不同
3、用法不同
---欢迎观看,觉得总结的还不错的请点个赞哦!更多内容持续更新。