vue相关面试题

1.Vue的数据双向绑定如何实现?Vue的数据双向绑定如何实现?

v-model指令或者.sync修饰

2.Vue中数据双向绑定原理?

采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调

就是把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue追踪依赖,在属性被访问和修改时通知变化

补充:Proxy 相比于 defineProperty 的优势

数组变化也能监听到                                                                    不需要深度遍历监听 

3.谈一谈Vue组件之间的参数传递?

父组件传给子组件:子组件通过props方法接收数据;

子组件传给父组件:$emit方法传递参数

兄弟间组件通信:使用vuex解决问题,先创建store对象;或者用eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适

4.路由的钩子函数?

当路由发生跳转的时候,会触发一系列钩子函数,如beforeEach(全局前置守卫)、afterEach(全局后置守卫)、beforeEnter(路由独享的守卫)一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。

beforeEach主要有3个参数to,from,next

to:route即将进入的目标路由对象

from:route当前导航正要离开的路由。

next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转 

beforeEnter 用于做登录的验证

5.Next的使用

next() 去下一步;

next( false )阻止跳转

next(' / ')或   next({ path:' / '  })跳转到不同路径

6.vue的路由实现hash模式 和 history模式

hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用 window.location.hash 读取。特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面

history模式:history采用HTML5的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更

7.说下你对vue生命周期的理解

总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后

在beforeCreate(创建之前:一次)阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化;

在 created(创建完成:一次)阶段,vue实例的数据对象data有了,el还没有;

在beforeMount(挂载之前:一次)阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点 ,data.message还未替换

在mounted(挂载完成)阶段,vue实例挂载完成 data.message成功渲染

当data变化时,会触发beforeUpdate(更新之前:n次)和updated(更新完成:n次)方法

beforeDestory(销毁之前:1次):实例销毁之前使用,在这里实例照常可以使用

destoryed(销毁完成:一次):实例销毁后使用,调用后Vue实例的所有东西会解除绑定,所有的事件监听器会被移除,所有的子实例会被销毁 ,但是dom结构依然存在;

什么是vue生命周期?

答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期

vue生命周期的作用是什么?

答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

vue生命周期总共有几个阶段?

答:它可以总共分为8个阶段:创建前/后、载入前/后、更新前/后、销毁前/销毁后

第一次页面加载会触发哪几个钩子?

会触发下面这几个beforeCreate(创建前)、created(创建完成)、beforeMount(挂载前)、mounted(挂载完成)

DOM 渲染在哪个周期中就已经完成?

答:DOM 渲染在 mounted(挂载完成) 中就已经完成了

8.vue的指令

v-if指令    判断是否隐藏

v-show指令

v-else指令

v-for指令    数据循环出来

v-bind:class指令     绑定一个属性

v-on指令

v-model指令:  实现双向绑定    它是一个语法糖:真实写法是  :value=" msg "@input     注(  :是v-bind,@是v-on)

v-text读取文本,不能读取html标签

v-html 能读取html标签

9.路由跳转

编程式( js跳转)this.$router.push()

声明式(标签跳转)<router-link to=" "></router-link>

10.路由对象

一个路由对象表示当前激活路由的状态信息,包含当前URL解析的信息,还有Url匹配到的路由记录

路由对象是不可变的,每次成功的导航后都会产生一个新对象

路由出现的多个地方:

1.在组件内,即this.$route  

2.在$route观察者回调中

3.route.match(location)的返回值

11.路由的懒加载

路由懒加载

按需加载会在页面第一次请求的时候,把相关路由组件块的js添加上;非按需加载则会把所有的路由组件块的js包打在一起。当业务包很大的时候建议用路由的按需加载(懒加载)

12.路由的传参

query传参


params传参


vue-router解决的问题

监听URL的变化,并在变化前后执行相应的逻辑

不同的URL对应不同的组件

提供多种方式改变URL的API(URL的改变不能导致浏览器刷新)

13.在Vue中使用插件的步骤

采用ES6的import ... from ...语法或CommonJS的require()方法引入插件

使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })

14.请列举出3个Vue中常用的生命周期钩子函数?

1.created: 实例已经创建完成之后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, watch/event事件回调. 然而, 挂载阶段还没有开始, $el属性目前还不可见

2.mounted: el被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted被调用时 vm.$el 也在文档内。

3.activated: keep-alive组件激活时调用

15.<keep-alive></keep-alive>的作用是什么?

如果你需要在组件切换的时候、保存一些组件的状态防止多次渲染,就可以使用keep -alive组件包集起来

它拥有两个独有的生命周期钩子函,分别是 activated(失去)和deactivated (得到)。用Keep-alive包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行deactivated钩子函数命中缓存存渲染后会执行activated钩子函数

生命周期 :

activated在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用;                                                           deactivated:组件被停用(离开路由)时调用

注意:使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了 .

属性有:

include - 字符串或正则表达式。只有名称匹配的组件会被缓存。

exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。

max - 数字。最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉

keep-alive

举例:

比如有一个列表页和详情页,用户经常执行打开详情—>返回列表—>打开详情。。。这种频率很高的页面,就可以对列表页组件使用<keep-alive>进行缓存,用户每次返回列表的时候,都是从缓存中快速渲染,而不是重新渲染,大大提高了性能。

16.指令v-el的作用是什么?

提供一个在页面上已存在的 DOM元素作为 Vue实例的挂载目标.可以是 CSS 选择器,也可以是一个 HTMLElement 实例

17.如何让CSS只在当前组件中起作用?

将当前组件的<style>修改为<style scoped>

18.Vue 组件 data 为什么必须是函数

每个组件都是 Vue 的实例。

组件共享 data 属性,当 data 的值是同一个引用类型的值时,改变其中一个会影响其他

vue-cli 工程技术集合介绍

1.构建的 vue-cli 工程都到了哪些技术,它们的作用分别是什么?

vue.js:vue-cli工程的核心,主要特点是 双向数据绑定 和 组件系统。

vue-router:vue官方推荐使用的路由框架。

vuex:专为 Vue.js 应用项目开发的状态管理器,主要用于维护vue组件间共用的一些 变量 和 方法。

axios( 或者 fetch 、ajax ):用于发起 GET 、或 POST 等 http请求,基于 Promise 设计。

vuex等:一个专为vue设计的移动端UI组件库。创建一个emit.js文件,用于vue事件机制的管理。

webpack:模块加载和vue-cli工程打包器

2.vue-cli 工程常用的 npm 命令有哪些?

1.下载 node_modules 资源包的命令:npm install

2.启动 vue-cli 开发环境的 npm命令:npm run dev

3.vue-cli 生成 生产环境部署资源 的 npm命令:npm run build

4.用于查看 vue-cli 生产环境部署资源文件大小的 npm命令:npm run build --report

3.vue-cli配置反向代理

vue-cli提供了配置反向代理的接口,即设置config/index.js中的proxyTable。配置如下:

配置dev
config中index


在组件中调用接口示例(axios):

axios配置

上述示例请求的地址会被解析为https://www.exaple.com/api/login。如果proxyTable中pathRewrite配置为空,则请求的地址被解析为https://www.exaple.com/login。

以上配置只是在开发环境(dev)中解决跨域。要解决生产环境的跨域问题,则在config/dev.env.js和config/prod.env.js里也就是开发/生产环境下分别配置一下请求的地址API_HOST,开发环境中我们用上面配置的代理地址api,生产环境下用正常的接口地址。配置代码如下:

开发环境和生产环境


对反向代理解决跨域过程的理解

通过伪造请求使得http请求为同源的,然后将同源的请求发送到反向代理服务器上,由反向代理服务器去请求真正的url,这样就绕过直接请求真正的url导致跨域问题。

axios:

get:

get请求

post:

post请求

post请求注意:如果后台接收的数据格式是 form-data格式 : ?name=a&age=20 你需要进行转换

默认是 x-www-form-urlencoded格式: {name:‘a’,age:‘20’} 这种格式的

怎样转换 :node给我们提供了一个库 qs 我们先将qs引进来

引入qs


然后:Qs.stringify({转换参数})


转换参数


axios封装:

axios封装


vue的SEO优化问题:

常用解决方案有3种

1.页面预渲染

2.服务端渲染

3.路由采用h5 history模式

vuex相关

1. vuex是什么?怎么使用?哪种功能场景使用它?

只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。

在main.js引入store,注入。新建了一个目录store,… export

场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车

2.解释vuex图中各个意思

state:Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。

mutations:mutations定义的方法动态修改Vuex 的 store 中的状态或数据

getters:类似vue的计算属性,主要用来过滤一些数据。

action:actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action

modules:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理

关于vue的一些对比

1.v-if 和 v-show 区别

相同点:都能实现元素的显示和隐藏

不同点:

1.v-if是真正的条件渲染,而v-show只是控制元素的dispaly属性,当需要做频繁切换显示隐藏时,推荐使用v-show,如果只是做一次,使用v-if;

2.v-if能使用template,而v-show不能使用

3.v-if有配套的v-else和v-else-if使用,而v-show没有

2.$route和$router的区别

$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数;

而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等

3.vue路由hash模式与history模式的区别

hash模式路由的哈希模式其实是利用了window可以监听onhashchange事件,也就是说你的url中的哈希值(#后面的值)如果有变化,前端是可以做到监听并做一些响应(搞点事情),这么一来,即使前端并没有发起http请求他也能够找到对应页面的代码块进行按需加载。后来人们给他起了一个霸气的名字叫前端路由,成为了单页应用标配

history模式我们先介绍一下H5新推出的两个神器:pushState与replaceState具体自行百度,简而言之,这两个神器的作用就是可以将url替换并且不刷新页面,好比挂羊头卖狗肉,http并没有去请求服务器该路径下的资源,一旦刷新就会暴露这个实际不存在的“羊头”,显示404


那么如何去解决history模式下刷新报404的弊端呢,这就需要服务器端做点手脚,将不存在的路径请求重定向到入口文件(index.html),前后端联手,齐心协力做好“挂羊头卖狗肉”的完美特效

总之,pushState方法不会触发页面刷新,只是导致history对象发生变化,地址栏会有反应

history模式下,build之后本地 index.html 打开是无效的。

hash模式下,build之后本地 index.html 打开正常!

大牛回答:hash模式url里面永远带着#号,我们在开发当中默认使用这个模式。那么什么时候要用history模式呢?如果用户考虑url的规范那么就需要使用history模式,因为history模式没有#号,是个正常的url适合推广宣传。当然其功能也有区别,比如我们在开发app的时候有分享页面,那么这个分享出去的页面就是用vue或是react做的,咱们把这个页面分享到第三方的app里,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式,但是使用history模式还有一个问题就是,在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人员配合让他配置一下apache或是nginx的url重定向,重定向到你的首页路由上就ok啦。

推荐阅读更多精彩内容