title: Vue相关问题
date: 2019-10-12 20:23:00
updated: 2019-10-12 20:23:00
tags: ['web前端面试']
Vue相关问题
1. Vue.js介绍
Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API;
Vue.js是一个构建数据驱动的Web界面的库。
Vue.js是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和 Vue生态系统支持的库开发的复杂单页应用。数据驱动+组件化的前端开发。
简而言之:Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API实现响应的数据绑定和组合的视图组件。核心是一个响应的数据绑定系统。
2. 谈谈你对vue的双向数据绑定原理的理解
vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.definePorperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指定(解析{{}}),最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化->视图更新;视图交互变化input->数据model变更的双向绑定效果
3. vue中常用的指令
v-for 、 v-if 、v-bind、v-on、v-show、v-else
4.v-if 和 v-show 区别
v-if按照条件是否渲染,v-show是display的block或none
5. MVVM 关键要素分析
- 响应式:vue 中的 data 数据,随便一改动,视图就能随着变化——如何监听这个变化的呢?
- 模板解析:模板看似是 html 但是它不是,因为它有指令,因此它是有逻辑的、动态的,而 html 只是静态的
- 渲染:页面一加载的显示,以及 data 变化之后的显示,如何做到的?特别是 rerender ,不能变化一点数据,页面全部都重新渲染。
6.vuex五个核心属性
https://blog.csdn.net/wh710107079/article/details/88181015
state, getters, mutations, actions, modules
主要包括以下几个模块:
- State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
- Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
- Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
- Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
- Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
7. Vue 中 computed、methods、watch三者的区别
https://blog.csdn.net/ly124100427/article/details/81328225
8. vue数据双向绑定原理
Vue内部通过Object.defineProperty
方法属性拦截的方式,把data
对象里每个数据的读写转化成getter
/setter
,当数据变化时通知视图更新
var obj = {}
var _name = '咱三'
Object.defineProperty(obj, "name", {
get: function() {
console.log('get')
return _name
},
set: function(newVal) {
console.log('set')
_name = newVal
}
})
console.log(obj.name)
obj.name = 'lisi'
9. vue路由
-
vue路由的两种模式,hash与history
对于Vue 这类渐进式前端开发框架,为了构建SPA(单页面应用),需要引入前端路由系统,这也就是Vue-router存在的意义。前端路由的核心,就在于——— 改变视图的同时不会向后端发出请求。
一、为了达到这个目的,浏览器提供了以下两种支持:
1、hash ——即地址栏URL中的#符号(此hsah 不是密码学里的散列运算)。
比如这个URL:http://www.abc.com/#/hello, hash 的值为#/hello。它的特点在于:hash 虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不会重新加载页面。
2、history ——利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法。(需要特定浏览器支持)
这两个方法应用于浏览器的历史记录站,在当前已有的back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改是,虽然改变了当前的URL,但你浏览器不会立即向后端发送请求。
history模式,会出现404 的情况,需要后台配置。
二、404 错误
1、hash模式下,仅hash符号之前的内容会被包含在请求中,如 http://www.abc.com, 因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回404错误;
2、history模式下,前端的url必须和实际向后端发起请求的url 一致,如http://www.abc.com/book/id 。如果后端缺少对/book/id 的路由处理,将返回404错误。
-
router跳转方法
router.push(location, onComplete?, onAbort?) router.replace(location, onComplete?, onAbort?) router.go(n)
-
router传递参数
// url/:id/:name router.push({'name':'routerName', 'params':{'id':'1', 'name':'lxl'}) // 获取参数方式 let id = this.$route.params.id; // url?id=1&name=lxl router.push({'path':'/resigner', 'query':{'id':'1', 'name':'lxl'}) // 获取参数方式 let id = this.$route.query.id;
10. 说一下对mvvm的理解
* MVVM --- Model -View- ViewModel
* 三者之间的联系,以及如何对应到各段代码
* ViewModel的理解,联系View和Model
11. vue中如何实现响应式
* 关键理解Object.defineProperty
* 将data的属性代理到vm上
12. vue中如何解析模板
* 模板:字符串,有逻辑,迁入js变量
* 模板必须转换为js代码(有逻辑,渲染html,js变量)
* render函数是什么样子的
* render函数执行是返回vnode
* updateComponent
13. vue的整个流程
* 第一步,解析模板成render函数
* 第二步,响应式开始监听
* 第三步,首次渲染,显示页面,且绑定依赖
* 第五步,data属性变化,触发render
14.谈谈你对 Vue 生命周期的理解?
(1)生命周期是什么?
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
(2)各个生命周期的作用
生命周期 | 描述 |
---|---|
beforeCreate | 组件实例被创建之初,组件的属性生效之前 |
created | 组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el 还不可用 |
beforeMount | 在挂载开始之前被调用:相关的 render 函数首次被调用 |
mounted | el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子 |
beforeUpdate | 组件数据更新之前调用,发生在虚拟 DOM 打补丁之前 |
update | 组件数据更新之后 |
activited | keep-alive 专属,组件被激活时调用 |
deadctivated | keep-alive 专属,组件被销毁时调用 |
beforeDestory | 组件销毁前调用 |
destoryed | 组件销毁后调用 |
补充: Vue / keep-alive
https://www.jianshu.com/p/4b55d312d297
15. 在什么阶段才能访问操作DOM?
在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM。
16. 使用Vue的好处
vue两大特点:响应式编程、组件化
vue的优势:轻量级框架、简单易学、双向数据绑定、组件化、视图、数据和结构的分离、虚拟DOM、运行速度快
17. vue 性能优化
- 使用CDN资源,减小服务器带宽压力
- 路由懒加载
- 将一些静态js css放到其他地方(如OSS),减小服务器压力
- 按需加载三方资源,如iview,建议按需引入iview中的组件
- 使用nginx开启gzip减小网络传输的流量大小
- 若首屏为登录页,可以做成多入口,登录页单独分离为一个入口
- 无状态的组件用函数式组件
- 使用uglifyjs-webpack-plugin插件代替webpack自带UglifyJsPlugin插件
- 子组件分割(第二个是拆分成子组件,因为 Vue 的更新是组件粒度的,虽然第次数据变化都会导致父组件的重新渲染,但是子组件却不会重新渲染,因为它的内部没有任何变化,耗时任务自然也就不会重新执行,因此性能更好)
- 事件的销毁
- 图片懒加载
18. VUE路由的hash模式与history模式的区别
https://blog.csdn.net/onlyhqm/article/details/85342532
https://blog.csdn.net/lyn1772671980/article/details/80804419
19. vue路由实现原理
https://segmentfault.com/a/1190000014822765?utm_source=tag-newest
20. 使用vue打包,vendor文件过大,或者是app.js文件很大https://www.cnblogs.com/wjunwei/p/9242142.html
21. vue路由懒加载及组件懒加载
https://www.cnblogs.com/-roc/p/9983177.html
22.VUE 组件通迅有哪些方式?
https://blog.csdn.net/mashibing_web/article/details/110821646
23. 使用vuex状态管理,刷新页面后会不会丢失
会,可以解决,使用插件vue-savedata
24. 介绍一下diff算法
https://www.cnblogs.com/wind-lanyan/p/9061684.html
25. mixin和mixins区别
mixin用于全局混入,会影响到每个组件实例,通常插件都是这样做初始化的。
Vue.mixin({
beforeCreate(){
// 会影响到每个组件的beforeCreate钩子函数
}
})
mixins最常用的扩展组件的方式。如果多个组件有相同的业务逻辑,就可将这些逻辑剥离出来,通过mixins混入代码。需要注意:mixins混入的钩子函数会先于组件内的钩子函数执行,并且在遇到同名选项的时候也会有选择性的进行合并。
vue中mixins的使用方法和注意点(详)
https://www.cnblogs.com/Ivy-s/p/9937173.html
26. VUE路由的hash模式与history模式的区别
https://blog.csdn.net/onlyhqm/article/details/85342532
https://blog.csdn.net/lyn1772671980/article/details/80804419
27. vue 的单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
这里有两种常见的试图变更一个 prop 的情形:
- 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。
在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
- 这个 prop 以一种原始的值传入且需要进行转换。 在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
28. 为什么说vue没有完全遵循mvvm
mvvm是指 模型-视图-视图模型,双向绑定,数据交互通过vm来实现
vue主题也是按照这样的设计模式的。只去改变数据。通过双向绑定,自动更新视图。
但是vue中添加了一个属 : $ref
通过ref可以拿到dom对象,通过ref直接去操作视图。这一点上,违背了mvvm
29. vue 的异步操作在哪里执行
30. vue 的动态路由
注意: 一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个展示商品的组件,对于所有 上架状态 各不相同的商品,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
const routes = [
{
path: "/",
component: () => import("@/views/Main.vue"),
redirect: "/index",
children: [
{
path: "/index/:id",
component: () => import("@/views/Index.vue"),
},
],
},
];