博客园整理了一下,有好的面试题欢迎大家发在评论区哟
1. 闭包
2. 数组去重
3. 原型和原型链
4. call,apply,bind三者的区别?
5. 请介绍常见的 HTTP 状态码(至少五个)
6. 深浅拷贝
7. 实现(5).add(3).minus(2)输出6
8. null和undefined区别
9. MVC和MVVC?
10. Vue生命周期
11. Vue数据双向绑定原理
12. Vue组件传参
13. 说说各浏览器存在的兼容问题
14. router和route
15. active-class属于Vue哪一个modules,有什么作用
16. v-if和v-show
17. computed和watch有什么区别
18.Vue 组件中 data 为什么必须是函数
19. vue中子组件调用父组件的方法
20. vue中 keep-alive 组件的作用
21. vue中如何编写可复用的组件?
22. Vue 如何去除url中的 #
23. Vue 中 key 的作用
24. Vue 中怎么自定义指令
25. Vue 中怎么自定义过滤器
26. NextTick 是做什么的
27. Vue 组件 data 为什么必须是函数
28. 计算属性computed 和事件 methods 有什么区别
29. scoped(死够扑的)
30. vue如何获取dom?
31. promise
32. vue常用指令有哪些
33.vue-loader是什么?使用和用途?
34.css样式局部化,如何让css只在当前组件起作用?scss和stytus样式穿透
1. 闭包
闭包指有权访问另一个函数中变量的函数,
MDN: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
B站视频:https://www.bilibili.com/video/BV1YJ411R7ap?from=search&seid=18157596230752413126
2. 数组去重
https://www.jianshu.com/p/9c3547450a52
3. 原型和原型链
https://search.bilibili.com/all?keyword=%E5%8E%9F%E5%9E%8B%E9%93%BE%20%E9%BB%91%E9%A9%AC
4. call,apply,bind三者的区别?
都是用来改变this指向的
call和apply都是function原型上的方法,每一个函数作为function的实例都可以调用这两个方法,而这两个方法都是用来改变this指向的
一般情况下this指向其调用者()
call
fun.call(thisArg,arg1,ary2,...)
主要作用可以实现继承
调用函数,改变this指向
var o={
name:'kangkang'
};
function fn(a,b){
console.log(this); //不写call则指向window
console.log(a+b); //3
}
fn.call(o,1,2);
继承
function father(uname,age,sex){
this.uname = uname;
this.age = age;
this.sex = sex;
}
function Son(uname,age,sex){
father.call(this,uname,age,sex);
}
var son=new Son('张学友',18,‘男’);
console.log(son);
apply
fun.apply(thisArg,[argsArray])
- thisArg:在fun函数运行时指定的this值
- argsArray:传递的值,必须包含在数组里面
- 返回值就是函数的返回值,因为它就是调用函数
var o={
name:'kangkang'
};
function fn(arr){
console.log(this);
console.log(arr);
}
fn.apply(o); //后面参数可省略
fn.apply(o,['pink']);
作用:调用函数,改变函数内部this指向
参数必须是数组
apply主要应用于借助数学对象等
var arr = [1,66,3,17];
var max = Math.max.apply(Math,arr);
var min = Math.min.apply(Math,arr);
console.log(max,min);
bind
bind()方法不会调用函数,但可以改变函数内部this指向
fun.bind(thisArg,arg1,arg2,...)
thisArg:在fun函数运行时指定的this值
arg1,arg2:传递的其他参数
返回由指定的this值和初始化参数改造的原函数拷贝
var o = {
name:'andy'
};
function fn(a,b){
console.log(this);
console.log(a+b);
};
var f = fn.bind(o,1,2);
f(); //产生了一个新函数
call的性能要比apply好一些,尤其当传递参数超过3个,后期开发可多用call
let arr = [1,2,3];
obj = {};
function fn(a,b,c){
fn.apply(obj,arr); //a=[1,2,3] b=c=undefined
fn.call(obj,...arr);//基于ES6的展开运算符,可以将数组中的每一项依次传递给函数
fn.call(obj,arr);
}
时间测试
console.time('A')
...
...
console.timeEnd('a')
5. 请介绍常见的 HTTP 状态码(至少五个)
状态码是由 3 位数组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理。
100 客户必须继续发出请求
101 客户要求服务器根据请求转换HTTP协议版本
2xx:成功–表示请求已被成功接收、理解、接受。
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
3xx:重定向–要完成请求必须进行更进一步的操作。
300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4xx:客户端错误–请求有语法错误或请求无法实现。
400 (错误请求) 服务器不理解请求的语法。
401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。
5xx:服务器端错误–服务器未能实现合法的请求。
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
6. 深浅拷贝
7. 实现(5).add(3).minus(2)输出6
~function(){
//==>每一个方法执行完,都要返回number这个类的实例,这样才可以继续调取number类原型中的方法(链式写法)
function check(n){
n = Number(n);
return isNaN(n)?0 : n;
}
function add(n){
n=check(n);
return this+n;
}
function minus(n){
n=check(n);
return this-n;
}
Number.prototype.add=add;
Number.prototype.minus=minus;
}
8. null和undefined区别
阮一峰:http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html
9.MVC和MVVC?
MVC是后端中的概念
- M (Model) 是指数据库中的数据
- V (View)
- C (Controller)
MVVC中是前端概念
- M (Model) 是data里数据(通过ajax等获取的数据)
- V (View) 是html结构
- VM (ViewModel)是new vue 中 new出来的对象就是VM,是V-M的调度者,提供了数据的双向绑定
最终实现V和M数据的同步,因此开发者只需关注业务逻辑,不需要手动操作Dom,mvvm是vue的核心
10. Vue生命周期
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- activated
- deactivated
- beforeDestroy
- destroyed
- errorCaptured
11、 Vue数据双向绑定原理
12、Vue组件传参
- 父子组件传参(props,$emit,$refs)
- 非父子组件传参(bus事件总线)
- 多级组件传参($attrs,$listeners)
https://blog.csdn.net/weixin_41535944/article/details/107327938?%3E
13、说说各浏览器存在的兼容问题
14、router和route
-
router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。
举例:history对象
$router.push({path:'home'});本质是向history栈中添加一个路由,在我们看来是 切换路由,但本质是在添加一个history记录
方法:
$router.replace({path:'home'});//替换路由,没有历史记录 route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等
这两个不同的结构可以看出两者的区别,他们的一些属性是不同的。
- $route.path
字符串,等于当前路由对象的路径,会被解析为绝对路径,如 "/home/news" - $route.params
对象,包含路由中的动态片段和全匹配片段的键值对 - $route.query
对象,包含路由中查询参数的键值对。例如,对于 /home/news/detail/01?favorite=yes ,会得到$route.query.favorite == 'yes' - $route.router
路由规则所属的路由器(以及其所属的组件) - $route.matched
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。 - $route.name
当前路径的名字,如果没有使用具名路径,则名字为空。
15. active-class属于Vue哪一个modules,有什么作用
active-class 属于vue-router的样式方法
当routerlink标签被点击时将会应用这个样式
使用有两种方法
routerLink标签内使用
<router-link to='/' active-class="active" >首页</router-link>
在路由js文件,配置active-class
<script>
const router = new VueRouter({
routes,
linkActiveClass: 'active'
});
</script>
<script>
const router = new VueRouter({
routes,
linkActiveClass: 'active'
});
</script>
在使用时会有一个Bug
首页的active会一直被应用
解决办法
为了解决上面的问题,还需加入一个属性exact,类似也有两种方式:
在router-link中写入exact
<router-link to='/' active-class="active" exact>首页</router-link>
在路由js文件,配置active-class
<script>
const router = new VueRouter({
routes,
linkExactActiveClass: 'active'
});
</script>
还可以不用exact这种方法去解决,例如
首页
路由中加入重定向
{
path: ‘/’,
redirect: ‘/home’
}
16 . v-if和v-show
17. computed和watch有什么区别
computed
computed是计算属性,也就是计算值,它更多用于计算值的场景
computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时重新调用对应的getter来计算
computed适用于计算比较消耗性能的计算场景
watch
watch更多的是[观察]的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作
无缓存性,页面重新渲染时值不变化也会执行
小结
当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed
如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化。
18.Vue 组件中 data 为什么必须是函数
vue组件中data值不能为对象,因为对象是引用类型,组件可能会被多个实例同时引用。
如果data值为对象,将导致多个实例共享一个对象,其中一个组件改变data属性值,其它实例也会受到影响。
19.vue中子组件调用父组件的方法
第一种方法是直接在子组件中通过this.emit向父组件触发一个事件,父组件监听这个事件就行了。
第三种都可以实现子组件调用父组件的方法,
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
props: {
fatherMethod: {
type: Function,
default: null
}
},
methods: {
childMethod() {
if (this.fatherMethod) {
this.fatherMethod();
}
}
}
};
</script>
20.vue中 keep-alive 组件的作用
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
<keep-alive>
<component>
<!-- 该组件将被缓存! -->
</component>
</keep-alive>
如果只想 router-view 里面某个组件被缓存
export default [
{
path: '/',
name: 'home',
component: Home,
meta: {
keepAlive: true // 需要被缓存
}
}, {
path: '/:id',
name: 'edit',
component: Edit,
meta: {
keepAlive: false // 不需要被缓存
}
}
]
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 这里是会被缓存的视图组件,比如 Home! -->
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!-- 这里是不被缓存的视图组件,比如 Edit! -->
</router-view>
21.vue中如何编写可复用的组件?
①创建组件页面eg Toast.vue;
②用Vue.extend()扩展一个组件构造器,再通过实例化组件构造器,就可创造出可复用的组件
③将toast组件挂载到新创建的div上;
④把toast组件的dom添加到body里;
⑤修改优化达到动态控制页面显示文字跟显示时间;
import Vue from 'vue';
import Toast from '@/components/Toast'; //引入组件
let ToastConstructor = Vue.extend(Toast) // 返回一个“扩展实例构造器”
let myToast = (text,duration)=>{
let toastDom = new ToastConstructor({
el:document.createElement('div') //将toast组件挂载到新创建的div上
})
document.body.appendChild( toastDom.$el ) //把toast组件的dom添加到body里
toastDom.text = text;
toastDom.duration = duration;
// 在指定 duration 之后让 toast消失
setTimeout(()=>{
toastDom.isShow = false;
}, toastDom.duration);
}
export default myToast;
22. Vue 如何去除url中的
vue-router 默认使用 hash 模式,所以在路由加载的时候,项目中的 url 会自带 #。如果不想使用 #, 可以使用 vue-router 的另一种模式 history
new Router({
mode: 'history',
routes: [ ]
})
需要注意的是,当我们启用 history 模式的时候,由于我们的项目是一个单页面应用,所以在路由跳转的时候,就会出现访问不到静态资源而出现 404 的情况,这时候就需要服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面
23. Vue 中 key 的作用
key
的特殊属性主要用在Vue
的虚拟DOM
算法,在新旧nodes
对比时辨识VNodes
。如果不使用key
,Vue
会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key
,它会基于key
的变化重新排列元素顺序,并且会移除key
不存在的元素。有相同父元素的子元素必须有独特的key
。重复的key
会造成渲染错误
具体参考 官方API
24. Vue 中怎么自定义指令
全局注册
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
局部注册
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
参考 官方文档-自定义指令
25. Vue 中怎么自定义过滤器
可以用全局方法
Vue.filter()
注册一个自定义过滤器,它接收两个参数:过滤器ID
和过滤器函数。过滤器函数以值为参数,返回转换后的值
Vue.filter('reverse', function (value) {
return value.split('').reverse().join('')
})
<!-- 'abc' => 'cba' -->
<span v-text="message | reverse"></span>
过滤器也同样接受全局注册和局部注册
26. NextTick 是做什么的
$nextTick
是在下次DOM
更新循环结束之后执行延迟回调,在修改数据之后使用$nextTick
,则可以在回调中获取更新后的DOM
具体可参考官方文档 深入响应式原理
27. Vue 组件 data 为什么必须是函数
因为js本身的特性带来的,如果
data
是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue实例的数据。如果将data
作为一个函数返回一个对象,那么每一个实例的data
属性都是独立的,不会相互影响了
28. 计算属性computed 和事件 methods 有什么区别
我们可以将同一函数定义为一个 method
或者一个计算属性。对于最终的结果,两种方式是相同的
不同点:
computed: 计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值对于
method
,只要发生重新渲染,method
调用总会执行该函数
29. scoped(死背死特)
<style scoped></style>
让css只在当前组件中起作用
30.vue如何获取dom?
答:ref="domName" 用法:this.$refs.domName