Vue的优点
- 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
- 双向数据绑定:保留了 angular 的特点,在数据操作方面更为简单
- 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
- 组件化:实现了HTML的封装和重用,在构建单页面应用方面有着独特的优势;
- 虚拟DOM:dom 操作是非常耗费性能的, 不再使用原生的 dom 操作节点,极大解放 dom 操作,但具体操作的还是 dom 不过是换了另一种方式
- 运行速度更快:相比较于 react 而言,同样是操作虚拟 dom ,就性能而言, vue 存在很大的优势。
- 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作
对MVVM的理解
- MVVM 由 Model、View、ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来;ViewModel 是一个同步View 和 Model的对象。
- 在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
- ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。
vue数据双向绑定原理
vue是采用数据劫持配合发布者-订阅者的模式的方式,通过Object.defineProperty()来劫持各个属性的getter和setter,在数据变动时,发布消息给依赖收集器(dep中的subs),去通知(notify)观察者,做出对应的回调函数,去更新视图。具体实现是通过以下几点:
- 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
- 实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
- 实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
Vue的生命周期
- beforeCreate:创建之前,此时还没有data和Method
- Created:
a) 创建完成,此时data和Method可以使用了
b) 在Created之后beforeMount之前如果没有el选项的话那么此时生命周期结束,停止编译,如果有则继续 - beforeMount:在渲染之前
- mounted:页面已经渲染完成,并且vm实例中已经添加完$el了,已经替换掉那些DOM元素了(双括号中的变量),这个时候可以操作DOM了(但是是获取不了元素的高度等属性的,如果想要获取,需要使用nextTick())
- beforeUpdate:data改变后,对应的组件重新渲染之前
- updated:data改变后,对应的组件重新渲染完成
- beforeDestory:在实例销毁之前,此时实例仍然可以使用
- destoryed:实例销毁后
页面第一次加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted
这几个钩子
何时需要使用beforeDestory
- 如果当前页面使用了$on方法,那需要在组件销毁前解绑
- 清除自己定义的定时器
- 解除事件的绑定scroll 、mousemove……
computed和watch的区别
- computed:计算属性,依赖其他属性,当其他属性改变的时候下一次获取computed值时也会改变,computed的值会有缓存
- watch:
a) 类似于数据改变后的回调
b) 如果想深度监听的话,后面加一个deep:true
c) 如果想监听完立马运行的话,后面加一个immediate:true
Vue中computed与method的区别
- 相同点:如果作为模板的数据显示,二者能实现响应的功能,唯一不同的是methods定义的方法需要执行
- 不同点:
a) computed 会基于响应数据缓存,methods不会缓存;
b) diff之前先看data里的数据是否发生变化,如果没有变化computed的方法不会执行,但methods里的方法会执行
c) computed是属性调用,而methods是函数调用
Vue中created与mounted区别
- 在created阶段,实例已经被初始化,但是还没有挂载至el上,所以我们无法获取到对应的节点,但是此时我们是可以获取到vue中data与methods中的数据的;
- 在mounted阶段,vue的template成功挂载在$el中,此时一个完整的页面已经能够显示在浏览器中,所以在这个阶段,可以调用节点了;
Vue中常用的指令有哪些?
- V-model:用于表单输入,实现表单控件和数据的双向绑定
- V-on:简写为@,基础事件绑定
- V-bind:简写为
:
,动态绑定一些元素的属性,类型可以是:字符串、对象或数组 - V-if:取值为true/false,控制元素是否需要被渲染
- V-else:和v-if指令搭配使用,没有对应的值。当v-if的值false,v-else才会被渲染出来
- V-show:指令的取值为true/false,分别对应着显示/隐藏。
- V-for:遍历data中存放的数组数据,实现列表的渲染。
- V-once: 通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新
Vue.use是做什么的,原理是什么?
- 用来注册使用插件或者组件的方法。
- 原理:
a) 检测组件是否注册,避免重复注册;
b) 处理入参,将第一个参数之后的参数归集,并在首部插入 this 上下文;
c) 第一个参数是对象就执行对象里面的install方法,是方法则直接执行这个方法,然后缓存;
d) 返回;
V-if和v-show的区别
- v-if 是真正的条件渲染,直到条件第一次变为真时,才会开始渲染。
- v-show 不管初始条件是什么都会渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。
- tips:v-show 则适用于需要非常频繁切换条件的场景;不频繁切换使用 v-if 更合理。
v-for和v-if的优先级
- Vue2.x版本里,v-for 优先于 v-if 被解析;Vue3.x版本里,v-if 优先于 v-for 被解析
- 如果同时出现,每次渲染都会先执行循环再判断条件,无论如何循环都不可避免,浪费了性能
- 要避免出现这种情况,则在外层嵌套template,在这一层进行v-if判断,然后在内部进行v-for循环
- 如果条件出现在循环内部,可通过计算属性提前过滤掉那些不需要显示的项
Vue中key值的作用?
Vue中key
值,作为唯一标识节点
加速虚拟DOM渲染
Vue组件的通信方式有哪些?
- 父子组件通信: 父组件通过props传输值给子组件;子组件通过$emit()方法将数据传递给父组件
- 兄弟组件通信: 通过一个空的Vue实例作为中间事件总线,用它来触发事件和监听事件
- 父子,兄弟,隔代组建通信: 通过vuex
Vue-router的模式
- hash模式:url里有
#
号,适合做后台管理系统 - history模式:url里没有
#
号,适合做前端宣传页面;利用pushstate和replacestate来将url替换但不刷新,但是有一个致命点就是,一旦刷新的话,就会可能404,因为没有当前的真正路径,要想解决这一问题需要后端配合,将不存在的路径重定向到入口文件。
路由跳转的方式及接收参数方式?
- 跳转方式有两种: 通过router-link标签;通过$router.push
- 接收参数的方式分别为:
a) Params: 只能使用name,不能使用path;参数不会显示在路径上;浏览器强制刷新参数会被清空
b) query:参数会显示在路径上,刷新不会被清空;name可以使用path路径;
// 第一种通过router-link标签
<router-link to=“/about?id=10">About</router-link>
// 第二种通过$router.push,传参方式有两种,
// 使用params: 参数不显示url地址上
// params路由传参
this.$router.push({name: ‘about’,params: {id: 1}});
// params接收参数
This.$router.params.id
// 使用query: 参数显示在地址上
this.$router.push({path: ‘/about’,query:{id: 1}});
// 使用query接收参数
this.$router.query.id
Vuex有哪些属性,分别有什么特性?
- State:单一状态树,用来放置vuex的基本数据;用来存储变量(后四个属性都是用来操作state里存储的变量的)
- Getters:对state里的变量进行过滤
- Mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)
- Action:和mutation功能大致相同,不同之处在于:
a) Action提交的是mutation,而不是直接变更状态。 也就是action是用来修改mutation并提交的 而 mutation是通过修改state
b) Action可以包含任意异步操作。(一般比较复杂的数据都在action中操作)
c) action先会执行异步操作再去调用mutation,随后才跟新state - Module:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
如果不使用vuex会带来哪些问题?
- 可维护性会下降
- 可读性会下降
- 增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。
Vue的性能优化有哪些?
代码方面:
- 避免v-if和v-for同时使用
- 确保key值的唯一性
- 节流、防抖
- 图片实现懒加载
- 第三方模块的按需导入
- 长列表数据,滚到可视区后动态加载
- 路由懒加载、异步组件
- 当需要通过循环给每个元素添加事件时,可使用事件的代理
- 尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
打包方面:
- 压缩代码
- splitChunks抽离公共文件
- sourceMap优化
- 使用cdn加载第三方模块