前言
最近在整理Vue相关的知识点,所以会不断更新一些内容,宝子可以持续关注哦
1.第一次加载页面会触发哪几个钩子函数?
首先Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模 板、挂载 Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
其次第一次加载页面会触发四个钩子函数,分别是:
- 1.创建前后:beforeCreate(),created()
- 2.挂载前后:beforeMount(),mounted()
2.怎么捕获 Vue 组件的错误信息?
首先要想捕获Vue组件的错误信息需要用到生命周期钩子函数errorCaptured() 它是组件内部钩子函数,在捕获一个后代组件的错误时被调用,接收 error、vm、info 三个参数,return false 后可以阻止错误继续向上抛出。
其次errorHandler 为全局钩子,使用Vue.config.errorHandler 配置,接收参数与 errorCaptured 一致,2.6 后可捕捉 v-on 与 promise 链的错误,可用于统一错误处理与错误兜底。
最后 errorCaptured 和 errorHandler 的触发时机都是相同的,不同的是 errorCaptured 发生在前,且如果某个组件的 errorCaptured 方法返回了 false,那么这个异常信息不会再向上冒泡也不会再调用 errorHandler 方法
3.Vue 常用的指令都有哪些?并且说明其作用
Vue官方提供的指令总共是有14个,常用的指令有11个,分别是:
- 1.v-model:本质上是一个语法糖,底层原理是由@input事件+value实现的,可用于表单元素实现双向数据绑定,也可实现父子组件传值
- 2.v-for:指令基于一个数组来渲染一个列表。建议设置key值,并且保证每个key值是独一无二的,这便于diff算法进行优化
- 3.v-show:的原理是动态为元素添加或移除
display:none样式,来实现元素的显示和隐藏 - 4.v-if:的原理是动态创建或移除元素,实现元素的显示和隐藏
- 5.v-else-if与v-else必须和v-if搭配使用,否则会报错
- 6.v-bind:为元素的属性动态绑定值
- 7.v-on:给标签绑定事件,可以简写为@
- 8.v-text:用于解析文本,但不能解析标签,并且会覆盖元素内部原有的内容!
- 9.v-html:可以把带有标签的字符串,渲染成真正的 HTML 内容!
- 10.{{}}:差值表达式,内容的占位符,不会覆盖原有内容
4.Vuex 的 5 个核心属性是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式, 采用集中式存储管理应用的所有组件的状态,解决多组件数据通信。其中五个核心属性分别是:
- 1.state:vuex用它来保存公共数据,state中保存的数据是响应式的,如果修改了数据,视图上的值也会一起变化
- 2.mutation:用于修改state中的数据,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler) 。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
- 3.getters:类似于vue.js中的计算属性,在state中数据的基础上,进一步对数据进行加工得到新数据
- 4.actions:actions 要修改state中的数据需要通过 mutation去修改,在 actions 中可以执行 store.commit,而且 actions 中可以有任何的异步操作。在页面中如果我们要调用用这个 actions,则需要执行 store.dispatch
- 5.modules:拆分模板,把复杂的场景按模块来拆开
5.Vue-Router 有哪几种路由守卫?
Vue.js官方文档提供的路由守卫总共有七个,分为三类:分别是全局, 单个路由独享, 或者组件级
- 全局前置守卫:router.beforeEach() 当导航触发时,依次执行
- 全局解析守卫:router.beforeResolve() 在所有组件内守卫和异步路由组件被解析之后调用
- 路由独享守卫:beforeEnter
- 组件内的守卫:分为三个:
beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave - 全局后置钩子:router.afterEach() 两个参数,没有next函数,也不会改变导航本身
6.Vue 的路由实现模式:hash 模式和 history 模式
hash模式与history模式是两种单页应用的路由模式:
hash模式 :底层原理是通过hashChange 实现,使用 URL 的 hash 来模拟一个完整的 URL, 其显示的网络路径中会有 “#” 号,hash 虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash后刷新, 也不会有问题
history模式:底层原理是通过popState, pushState()实现,history模式就是美化后的hash模式,路径中不包含“#”。依赖于Html5 的 history api由于改变了地址, 刷新时会按照修改后的地址请求后端, 需要后端配置处理, 将地址访问做映射, 否则会404
解决方案: 为什么哈希模式打包不会出现问题?是因为哈希模式会默认去index页面,而history运行代码发现没有token会去login页面,但打包上线只有一个index页面,这就需要后端的配合,看后端是什么应用,但是原理都是一样的,需要后端把请求都转到index页面
7.Vue2.0 兼容 IE 哪个版本以上吗?
因为 Vue 的响应式原理是基于 Object.defineProperty()来劫持对象属性的setter和getter来实现的,而这个方法不支持 ie8 及以下,部分兼容 ie9 ,完全兼容 10 以上
8.你知道 style 上加 scoped 属性的原理吗?
什么是 scoped
在 Vue 组件中,为了使样式私有化(模块化),不对全局造成污染,可以在style 标签上添加 scoped 属性以表示它的只属于当下的模块,局部有效。如果一个项目中的所有 Vue 组件 style 标签全部加上了 scoped,相当于实现了样式的私有化。如果引用了第三方组件,需要在当前组件中局部修改第三方组件的样式,而又不想去除 scoped 属性造成组件之间的样式污染。此时只能通过穿透scoped 的方式来解决
scoped 的实现原理:
Vue 中的 scoped 属性的效果主要通过 PostCSS 转译实现,即:PostCSS 给所有 dom 添加了一个唯一不重复的动态属性,然后,给 CSS 选择器额外添加一个对应的属性选择器来选择该组件中 dom,这种做法使得样式私有 化
9.如何对 Vue 首屏加载实现优化?
1、把不常改变的库放到 index.html 中,通过 cdn 引入
2、Vue 路由的懒加载
3、不生成 map 文件
4、Vue 组件尽量不要全局引入
5、使用更轻量级的工具库
6、开启 gzip 压缩
7、首页单独做服务端渲染
10.Vue 数据双向绑定的原理是什么?
Vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时 发布消息给订阅者,触发相应的监听回调。
12.Vue 组件 data 为什么必须是函数
首先会报错呀,其次这样是为了避免组件之间的数据互相影响。 同一个组件被多次复用会创建多个实例,如果data是一个对象的话,这些实例会共享同一个data,是一个浅拷贝,改变一个就会影响其他。为了保证组件的数据独立,将组件中的data写成一个函数,并且数据以函数返回值的形式定义,这样每次组件复用,都会返回一份新的data
13.Vue 组件里的定时器要怎么销毁?
销毁定时器的操作一般是在beforeDestroy钩子中进行,根据定时器的数量不同可以有两种解决方式:
1.多定时器解决方法:
-
在data函数里创建一个对象timer,给每个定时器取个名字一一映射在对象timer中
-
在beforeDestroy钩子中通过for(let k in this.timer){ clearInterval (k)}清除定时器。
2.单定时器解决方法:
const timer = setInterval(() =>{
// 某些定时器操作
}, 500);
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once(‘hook:beforeDestroy’, () => {
clearInterval(timer);
})
- 多定时器的清除方法也适用于单定时器 (注:需掌握$once,for in和for of 的区别)
14.Vuex 的出现解决了什么问题?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
解决了两个问题:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。 (注:需掌握state,mutations,actions,getters)
15.v-for 循环为什么一定要绑定key ?
key 的作用主要是为了高效的更新虚拟DOM ,建议使用v-for循环渲染元素时,需要传入一个唯一的key值,这个key相当于每个虚拟dom的标识,vue默认采用的是就地复用原则,如果你没有key会销毁元素并重新创建,如果有key的话会将新旧虚拟dom进行一个比对,看key值是否一样来决定就地复用还是就地更新
16.vue中computed 和watch 的区别是什么?
computed计算属性就是为了简化template里面模版字符串的计算复杂度、防止模版太过冗余。它具有缓存特性
computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象,一般用于监控路由、input输入框的值特殊处理等等,它比较适合的场景是一个数据影响多个数据,它不具有缓存性
- watch:监测的是属性值, 只要属性值发生变化,其都会触发执行回调函数来执行一系列操作。
- computed:监测的是依赖值,依赖值不变的情况下其会直接读取缓存进行复用,变化的情况下才会重新计算。
除此之外,有点很重要的区别是:计算属性不能执行异步任务,计算属性必须同步执行。也就是说计算属性不能向服务器请求或者执行异步任务。如果遇到异步任务,就交给侦听属性。watch也可以检测computed属性。
17.什么vuex ,谈谈你对它的理解?
- 首先vuex的出现是为了解决web组件化开发的过程中,各组件之间传值的复杂和混乱的问题
- 将我们在多个组件中需要共享的数据放到store中,
- 要获取或格式化数据需要使用getters,
- 改变store中的数据,使用mutation,但是只能包含同步的操作,在具体组件里面调用的方式
this.$store.commit('xxxx') - Action也是改变store中的数据,不过是提交的mutation,并且可以包含异步操作,在组件中的调用方式
this.$store.dispatch('xxx'); 在actions里面使用的commit('调用mutation')
18.vue实例是挂载到那个标签上的?
vue实例最后会挂载在body标签里面,所以我们在vue中是获取不了body 标签的,如果要使用body标签的话需要用原生的方式获取
19.为什么避免 v-if 和 v-for 用在一起
因为在v-if和v-for用在同一个元素上时,因为v-for要比v-if的优先级高,所以会先执行循环,再进行判断,这样无论条件判断的结果如何,循环都会执行。所以要避免她们用在一起,如果需要的话,可以在外层加一个template,v-if用在template上,这样就可以实现先判断再根据判断结果决定是否执行循环了。
20.请说出路由配置项常用的属性及作用
路由常用的配置项总共有七个,分别是:
(1)path: 路由请求的路径
(2)component: 路径匹配成功后需要渲染的组件或者页面
(3)redirect: 重定向路由请求的路径
(4)children: 路由嵌套,嵌套中的path不要加‘/’,因为以‘/’开头的嵌套路径会被当作根路径
(5)name: 命名路由,给当前路由取一个别名
(6)props: 路由解耦,路由传参的一种方式,针对动态路由
(7)meta: 路由元信息,当前路由所携带的一些信息
21.编程式导航使用的方法以及常用的方法
编程式导航使用方法分为4种
1.路由跳转 : this.$router.push()
2.路由替换:this.$router.replace()
3.后退:this.$router.back()
4.前进:this.router,push这种方式是使用的最多的
22.Vue 怎么实现跨域
1.实现跨域首先要知道什么是跨域,跨域是指浏览器不允许当前页面的所在源去请求另一个源的数据,源指协议,端口,域名,只要这三个中有一个不同就是跨域
2.前端解决跨域的办法有三种;分别是JSONP,CORS,代理(Proxy),其中代理(Proxy)是相对最常用的,Vue脚手架搭建项目是配置代理的,只需要在Vue.config里面配置一下就可以使用了
23.你对 Vue.js 的 template 编译的理解?
1.template的作用是模板占位符,里面写html结构,可帮助我们包裹元素
2.循环template的时候,并不会渲染到页面上
3.template身上只能使用v-if v-else-if v-else v-for 这些指令
24.怎样理解Vue的单向数据流
单向数据流是指数据从父级组件传递给子组件,只能单向绑定。 子组件内部不能直接修改从父级传递过来的数据。 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定: 父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
单向数据流可以防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为 最新的值。 如果你要修改父组件传过来的值时,只能通过 $emit 派发一个自定义事件,父组件接收到后, 由父组件去修改。
25.怎么定义 Vue-Router 的动态路由?怎么获取传过来的动 态参数?
可以通过query,prams两种方式定义,query通过route.query.参数名 接收,prams通过route.params.参数名 接收(注意确认router和route)
26.query 和 params 之间的区别是什么?
query和params是两种传参方式,它们主要有两处不同:
1.params必须要由命名路由name引入,query即可由path引入也可由name引入,不过一般推荐用path引入
2.params传参,path路径后面一定要添加参数,不添加页面刷新数据会丢失,query传参是在url后面拼接参数,path路径后面可以不添加
27.vue.use()的作用及应用?
用来注册插件,里面有个install函数
28.$nextTick的作用及应用场景?
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM,比如父子传值,props接收是异步的
29.mutations和actions的区别?
-
mutation专注于修改state,理论上来讲是修改state的唯一途径。action是用来存放一些异步操作的
-
mutation是必须同步执行的,而action可以是异步的,但是它本身是同步的,而且action是不能直接修改state的。只能通过commit来提交mutation,通过mutation来修改数据。
-
流程顺序不同,一般我们使用时会通过dispatch来调用action,action会提交mutation来修改state
30.虚拟DOM怎么渲染到页面?
render函数会返回一个函数创建的node节点,最后会被beforeMount接收到。beforeMount接受到之后会将其节点进行渲染。
31.object.defineProperty与Proxy的区别?
- Proxy效率更高,可以处理一类操作
- object.defineProperty只能操作对象的属性
- Proxy能直接监控数组的操作
- object.defineProperty对数组的响应只能操作七个方法
- push/pop/shift/unshift/splice/sort/reverse
PS: 本文还在更新中,敬请期待
如果内容有错误的地方欢迎指出(觉得看着不理解不舒服想吐槽也完全没问题);如果有帮助,欢迎点赞和收藏,转载请著明出处,如果有问题也欢迎私信交流