1.$route和$router的区别?
-
routes : 数组。 路由匹配规则
-
router : 对象。 路由对象
-
$router : 对象。 用于跳转路由 和 传递参数
-
$route :对象。 用于接收路由跳转参数
1.Vue的生命周期方法有哪些?
- beforeCreate 初始化实例前(在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问。)
- created 实例创建完成之后被调用
- beforeMount 挂载开始之前被调用(相关的 render 函数首次被调用)
- mounted 挂载之后 (在当前阶段真实的DOM挂载完毕,数据完成双向绑定,可以访问DOM节点)
- beforeUpdate 数据更新前调用 (不会触发重新渲染过程)
- updated 更新完成之后
- beforeDestory 实例销毁之前调用
- destroyed 实例销毁之后调用 (Vue实例指示的东西都会解绑,所有事件监听移除)
- activated keep-alive专属,组件被激活时调用
- deactivated keep-alive专属,组件被销毁是调用
异步请求在哪一步发起?
可以在钩子函数 created、beforeMount、mounted 中进行异步请求,因为在这三个钩子函数中,data已经创建,可以将服务器端返回的数据进行赋值。
如果异步请求不需要依赖 DOM 推荐加载 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:
能更快获取到服务端数据,减少页面loading时间;
如果依赖DOM元素:需要再mounted里面进行请求
2.与 2.x 版本生命周期相对应的组合式 API
- beforeCreate -> 使用 setup()
- created -> 使用 setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
3.为什么data是一个函数
组件的data写成一个函数,数据以函数返回值形式定义
这样每复用一次组件,就会返回一分新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。
而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。
- 避免组件被复用时,数据存在引用关系。
- vue组件可能存在多个实例,如果使用对象形式,会导致多个组件共用一个data,从而使一个组件影响其他组件。
- 如果用函数定义,会返回一个全新的对象,避免了组件间之间data的相互影响。
4.【几乎必问】vue组件传值
- props 和 $emit。
父组件向子组件传递数据是通过props传递的,
子组件传递给父组件是通过$emit触发事件来做到的。
- $parent 和 $children 获取单签组件的父组件和当前组件的子组件。
- $refs 获取组件实例
- 父传子孙:provide 和 inject
- vuex 状态管理(实现不同组件之前的数据共享)
--------------------------------------------
父传子
1.子组件props定义变量
2.父组件在使用子组件时通过行内属性给props变量传值
特点:单向数据流
子传父
1.子组件:$emit触发父的事件
2.父在使用组件用@自定义事件名=父的方法 (子把值带出来)
特点:事件监听
非父子组件
vuex
4.Vue 的单项数据流
- 数据总是从父组件传递到子组件,子组件没有权利修改从父组件传过来的数据,只能请求父组件对原始数据进行修改。
5.computed 和 watch 的区别和运用的场景。
- computed 是计算属性,依赖其他属性计算值,并且computed的值具有缓存性,当计算值发生变化时才会返回内容。
- watch 监听到值得变化就会调用。
计算属性一般用在模板渲染中,某个值是依赖其它响应对象甚至是计算属性而来;
而侦听属性适用于观测某个值的变化去完成一段复杂的业务逻辑。
6.Vuex
- vuex可以实现不同组件之间的状态共享
- vuex可以实现组件内数据的持久化
为什么需要 vuex
由于组件只维护自身的状态(data),组件创建时或者路由切换时,组件会被初始化,从而导致 data 也 随之销毁。
使用方法
在 main.js 引入 store,注入。只用来读取的状态集中放在 store 中, 改变状态的方式是提交
mutations,这是个同步的事物,异步逻辑应该封装在 action 中。
什么场景下会使用到 vuex
如果是 vue 的小型应用,那么没有必要使用 vuex,这个时候使用 vuex 反而会带来负担。组件之间的 状态传递使用 props、自定义事件来传递即可。 但是如果 涉及到 vue 的大型应用 ,那么就需要类似于 vuex 这样的集中管理状态的状态机来管理所有 组件的状态。例如登录状态、加入购物车、音乐播放等,总之只要是开发 vue 的大型应用,都推荐使 用 vuex 来管理所有组件状态
- vuex的核心概念
(1)、state:设置初始值
(2)、getter:允许组件从state中获取数据
(3)、Mutation:修改state中状态的方法,且必须是同步函数
(4)、Action:用于提交mutation,可以包含任何异步请求
(5)、Module
- vuex流程
在vue组件里面,通过dispatch来触发actions提交修改数据的操作,
然后通过actions的commit触发mutations来修改数据,mutations接收到commit的请求,就会
自动通过mutate来修改state,最后由store触发每一个调用它的组件的更新。
7.Vue 的性能优化
- 不需要响应式的数据不要放在 data 中
- v-if 和 v-show 区分使用场景
- computed 和 watch 区分场景使用
- v-for 遍历必须加 key,key最好是id值,且避免同时使用 v-if
- 长列表滚动到可视区域加载
- 防止内部泄露,组件销毁后把全局变量和时间销毁
- 图片懒加载
- 路由懒加载
- SPA 页面采用keep-alive缓存组件
- key保证唯一
- 第三方模块的按需加载
- 适当采用 keep-alive 缓存组件
- 防抖、节流
- 增加loading用户体验
- 骨架屏
----
- 预渲染
- 服务端渲染SSR
----
- 压缩代码
- 使用cdn加载第三方模块
8.vue首屏加载慢的原因,解决方案,怎么解决白屏问题
- 首屏加载慢原因:第一次加载页面有很多组件数据需要渲染
- 解决方案:
(1)路由懒加载
(2)UI组件按需加载
(3)gzip按需加载
- 解决白屏:
(1)使用v-text渲染数据
(2)使用{{}}语法渲染数据,同时使用v-cloak指令
9.SPA首屏加载速度慢的怎么解决?
- 加载慢的原因
1、网络延时问题
2、资源文件体积是否过大
3、资源是否重复发送请求去加载了
4、加载脚本的时候,渲染内容堵塞了
- 常见的几种SPA首屏优化方式
1、减小入口文件积
2、静态资源本地缓存
3、UI框架按需加载
4、图片资源的压缩
5、组件重复打包
6、开启GZip压缩
7、使用SSR
10.说说你对spa单页面的理解
- spa仅在web页面初始化的时候加载html、js、css
- 页面一旦加载完成就不会因为用户的操作而进行页面的重新加载和渲染
- 页面的变化是利用路由机制实现html内容的变换,避免页面的重新加载
11.为什么vue采用异步渲染
- vue是组件级更新,当前组件里的数据变了,它就会去更新这个组件。
当数据更改一次组件就要重新渲染一次,性能不高,为了防止数据一更新就更新组件,所以做了个异步更新渲染。
-(核心的方法就是nextTick)
12.第一次页面加载会触发哪几个钩子?
- 第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
13.Vue的父子组件生命周期钩子函数执行顺序
加载渲染过程
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created
-> 子 beforeMount -> 子 mounted -> 父 mounted
子组件更新过程
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
父组件更新过程
父 beforeUpdate -> 父 updated
销毁过程 父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
总结: 父组件先开始 子组件先结束
14.vue-router 动态路由是什么?有什么问题。
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个
User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用 “ 动态路径参数 ” ( dynamic segment )来达到这个效果:
const User = {
template: "User",
};
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: "/user/:id", component: User },
],
问题 : vue-router 组件复用导致路由参数失效怎么办?
解决方案 :
1 、通 过 watch 监听 路由参数再发请求
watch:{
"router":function(){
this.getData(this.$router.params.xxx)
}
}
2 、用 :key 来阻止复用
router-view :key="$route.fullPath"
15.Vuex 页面刷新数据丢失怎么解决?
需要做 vuex 数据持久化 ,一般使用本地储存的方案来保存数据,
16.路由传参
-使用router-link时
query传参:<router-link :to="/xxx/xxx?id=xx&name=xxx"></router-link>
<router-link :to="{
path:'/xxx/xx',
query:{
id:xxx,
name:xxx
}
}">跳转</router-link>
使用this.$route.query.id获取
params传参
<router-link :to="/xxx/xxx/001/sddf"></router-link>
<router-link :to="{
name:'asd',
params:{
id:xxx,
name:xxx
}
}"></router-link>
-router.js
{
name:'asd',
path:'xxxx/:id/:name',
component:Detail
}
接收参数this.$route.params.id
-使用params传参时,若是对象写法,需要在router.js中配置响应的name属性,并且需要占位。
-使用编程式路由导航
this.$router.push({
name:'xxx',
params:{
id:xxx,
title:xxx
}
})
17.路由守卫
对路由进行权限控制
router.beforeEach:全局前置路由守卫,to:目标路由,from:来源路由,next():放行;自定义参数需要配置在路由元信息(meta)里配置,用来控制权限。
router.afterEach():全局后置路由守卫,可用于动态更改页面标题。
beforeEnter():单个路由配置,路由独享守卫,对某一个路由进行权限设置。
beforeRouteEnter():组件内置守卫,通过路由规则,进入组件之前调用。
beforeRouteLeave():组件内置守卫,通过路由规则,离开组件之前调用。
18.vue3的优点
-性能提升
打包大小减少41%
初次渲染快55%,更新渲染快133%
内存减少54%
-源码升级
使用proxy代替defineproperty实现响应式
重写虚拟dom的实现和剔除多余代码(tree-shaking)
-vue3可以更好的支持typescript
-新特性
composition API(组合api)
setup配置
ref与reactive
新的内置组件
fragment
teleport
新的生命周期钩子
移除keycode支持作为v-on的修饰符
data始终是一个函数
19.watchEffect函数和computed的区别
-computed:是计算函数,注重计算出来的值,所以必须写返回值
-watchEffect:是监视函数,注重过程,不用写返回值
20.【几乎必问】Vue中key值作用
1.vue在渲染的时候,会 先把 新DOM 与 旧DOM 进行对比, 如果dom结构一致,则vue会复用旧的dom。 (此时可能造成数据渲染异常)
2.使用key可以给dom添加一个 唯一标识符,让vue强制更新dom
[vue中key值作用逐字稿]
面试官你好,我是这么理解key值的,key值的主要作用是给元素添加一个唯一标识符,用于提高vue渲染性能,当data发生变化的时候,vue会使用diff算法来对比新旧虚拟DOM.如果key值相同,才会考虑复用元素.如果key值不同,则会强制更新元素.一般通过给元素key设置为id,来保证vue更新数据的时候可以最大限度复用相同的key值的元素.
v-for 循环为什么一定要绑定key ?
给每个dom元素加上key作为唯一标识 ,diff算法可以正确的识别这个节点,使页面渲染更加迅速!
21.数组常用的方法?哪些方法会改变原数组,哪些不会
会改变原数组:
pop (删除数组的最后一个元素并返回删除的元素)
push(向数组的末尾添加一个或更多元素,并返回新的长度)
shift(删除并返回数组的第一个元素)
unshift(向数组的开头添加一个或更多元素,并返回新的长度)
reverse(反转数组的元素顺序)
sort(对数组的元素进行排序)
splice(用于插入、删除或替换数组的元素)
不会改变原数组:
concat---连接两个或更多的数组,并返回结果。
every---检测数组元素的每个元素是否都符合条件。
some---检测数组元素中是否有元素符合指定条件。
filter---检测数组元素,并返回符合条件所有元素的数组。
indexOf---搜索数组中的元素,并返回它所在的位置。
join---把数组的所有元素放入一个字符串。
toString---把数组转换为字符串,并返回结果。
lastIndexOf---返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。
map---通过指定函数处理数组的每个元素,并返回处理后的数组。
slice---选取数组的的一部分,并返回一个新数组。
valueOf---返回数组对象的原始值
22.什么是原型链?
每一个实例对象上有一个proto属性,指向的构造函数的原型对象,构造函数的原型对象也是一个对象,也有proto属性,这样一层一层往上找的过程就形成了原型链。
23.什么是闭包?闭包有哪些优缺点?
- 概念:函数嵌套函数,内部变量能访问外部变量,这个变量称为自由变量
- 解决的问题:保存变量
- 带来的问题:会造成内存泄漏问题
- 闭包的应用:防抖节流
24.es6有哪些新特性?
- 模板字符串
- 箭头函数
- for-of(用来遍历数据—例如数组中的值。)
- ES6 将 Promise 对象纳入规范,提供了原生的 Promise 对象。
- 增加了 let 和 const 命令,用来声明变量。
- 还有就是引入 module 模块的概念
25.常见的盒子垂直居中的方法有哪些请举例3种?
利用子绝父相定位方式来实现
<style>
.container{
width: 300px;
height: 300px;
position: relative;
}
.conter{
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
</style>
利用Css3的transform,可以轻松的在未知元素的高宽的情况下实现元素的垂直居中。
<style>
.container{
position: relative;
}
.conter{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
</style>
flex
<style>
.container{
display: flex;
justify-content: center;
align-items: center;
}
.conter{
}
</style>
26.js数据类型有哪些,区别是什么
- 基本类型:string,number,boolean,null,undefined,symbol,bigInt
- 引用类型: object,array
- 基本类型存储在栈中,空间小,操作频繁
- 引用数据类型存放在堆中,它的地址在栈中,一般我们访问就是它的地址
27.什么是同源策略
所谓同源策略就是浏览器的一种安全机制,来限制不同源的网站不能通信(域名、协议、端口号相同)
28.promise是什么,有什么作用
- promise 是一个对象, 可以从改变对象获取异步操作信息
- 他可以解决回调地狱的问题,也就是异步深层嵌套问题
29.let和const 的区别是什么
- let 命令不存在变量提升,如果在 let 前使用,会导致报错
- 如果块区中存在 let 和 const 命令,就会形成封闭作用域
- 不允许重复声明
- const定义的是常量,不能修改,但是如果定义的是对象,可以修改对象内部的数据
30.== 和 ===的区别
- ==是非严格意义上的相等
- 值相等就相等
- ===是严格意义上的相等,会比较两边的数据类型和值大小
- 值和引用地址都相等才相等
31.什么是防抖和节流,js 如何处理防抖和节流
-
首先 防抖就是触发下一个事件时停掉上一个事件
-
节流是 触发当前事件需要在上一个事件结束以后
-
通过设置节流阀(定时器)
32.跨域
跨域原因:浏览器出于安全考虑保护资源,同源策略。(协议、域名、端口号)
解决跨域:
jsonP 但只能使用get 原理-将请求的接口设置给script标签的src属性传递一个函数给后台实现跨域。后台响应的是一个函数调用
cors:最常用。
反向代理:本地前端发送到本地后端,不会跨域,(同源)本地后端接收请求后转发到其他服务器(服务器和服务器之间不会跨域)代理是需要路径中的特殊标志。
33.