一、computed和methods
共同点:computed能实现的methods也能实现;
不同点:computed是基于它的依赖进行缓存的。computed只有在它的相关依赖发生变化才会重新计算求值。 而只要它的相关依赖没有发生变化,多次访问会立即返回之前的计算结果,而不必再次执行计算。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。也就是说当我们不希望有缓存,用方法来替代。
二、watch和computed
共同点:都是以Vue的依赖追踪机制为基础的,都是希望在依赖数据发生改变的时候,被依赖的数据根据预先定义好的函数,发生“自动”的变化。
不同点:watch擅长处理的场景:一个数据影响多个数据;computed擅长处理的场景:一个数据受多个数据影响。虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器,当需要在数据变化时执行异步或开销较大的操作时,通过侦听器最有用。
三、Query和Params的区别
1.使用query传参的时候,name,path都可以引入,但使用params传参的时候只能使用name进行引入。
2.接收参数的时候使用this.$route.params.name或者this.$route.query.name
3.进行路由跳转的时候,我们使用this.$router.push('路径')
4.params传参需要占位符,需要修改路由规则配置,query不需要
5.params传参形式本质改变的是path路径,但是query是不会改变当前路径的
6.params刷新参数会消失,可以在路由里面配置,防止丢失
四、MVVM和MVC的区别
MVC backbone.js框架就是这种模式
由Model,Controller,View组成,
Model负责保存应用数据,与后端数据进行同步 ;
Controller:负责业务逻辑,根据用户行为对Model数据进行修改
View:负责视图展示,将model中的数据可视化
缺点:数据流混乱,model和view数据交互,维护非常麻烦;view比较庞大,
MVVM
可分解成Model,View,ViewModel
View和Model之间被分离开来,互相不知道对方的存在
优点:低耦合高内聚,view可以独立于Model的变化和修改,可重用性,独立开发,可测试
高内聚:相关度比较高的部分尽可能的集中,不要分散
低耦合:两个相关的模块尽可能把依赖部分的降到最低,不要让两个系统产生依赖
五、谈谈对Vue的看法
vue是一个MVVM的一个框架, 适合做电商类,后台管理系统的项目,项目中都用到vue全家桶,vue
vue-router vuex axios,生命周期函数等技术
对比其它框架的优点 是一个渐进式javascript框架,
特点:响应式编程,组件化,
优势:轻量级框架,简单易学,双向数据绑定,组件化、视图、数据、结构的分离、虚拟DOM、运行速度快,是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和dom,这样大大加快了访问速度,和提升用户体验。而且他的第三方ui库很多,节省开发时间
六、深浅拷贝
1.浅拷贝:只拷贝地址,任一方的改变都会影响另一方
2.深拷贝:只拷贝值,不拷贝地址
jQuery里面还有一种方法 $.extend(true,[],object)true为深拷贝,false为浅拷贝
快速深拷贝的方法json.parse(json.Stringify(obj))先转字符串 再转对象,会破坏原型链,无法拷贝function的属性
深层用递归
Object.assign(obj1,obj2)
七、SPA--------single page
application。单页面应用,即一个web项目就只有一个页面(即一个HTML文件)。
是把整个项目的所有页面的所有内容分成可以重复利用的,可以任意调整的组件,
每个组件就是一个独立的部分(包括html,css和javascript代码)。
再做一个html(基本上啥也没有),这个html就是一个页面容器,需要放那个组件时,直接引入就行。跳转时,直接跳转组件就行。
当需要加载某个组件时,js会动态创建这些组件里的HTML,CSS。
优点 用户体验好,快,避免重复渲染,前后端职责分离架构清晰
缺点 初次加载耗时多
八、双向数据绑定
它的双向数据绑定采用数据劫持发布-订阅者模式的方法,通过Object.defineProperty(),
来劫持各个属性的getter和setter,把数据设置为访问属性,这样数据改变时就会触发set(写入)
和get(读取)方法,通过这两个函数实现对视图的更新
第一步需要observe的数据对象进行递归遍历,都加上getter和setter,这样,如果给这个对象
的某个值赋值,就会触发setter,就能监听到数据变化
第二步compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将
每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
第三步Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
在自身实例化时往属性订阅器(dep)里面添加自己
自身必须有一个update()方法
待属性变动dep.notice()通知时,能调动自身的update()方法,并触发Compile中绑定的回调,
则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observe、Compile和Watcher三者,通过Observer
来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher
搭起Observer和Compile之间的通信桥梁,达到数据变化->视图更新;视图交互变化(input)->
数据model变更的双向绑定效果。
九、生命周期钩子函数
创建时期:
beforeCreate实例创建之前,现在还输不出data和method中的数据
created实例创建时触发但是不能调用$el
挂载时期
beforeMount在内存中渲染好了模板,但是并未把模板挂载到页面中
mounted此时可以获取$el
修改时期
beforeUpdata页面还没更新,数据已经更新了
updated页面和data数据保持一致
销毁时期
beforeDestroy实例身上的data和methods,过滤器,指令方法,还处于可用状态
destroyed组件已经被完全销毁,组件中的数据,方法,指令,过滤器都已经不可用了
activated keep-alive组件激活时调用
deactivated keep-alive组件停用时调用
善用keep-alive 用于缓存组件和清除缓存
errorCaptured 阻止错误继续上传
十、Vuex 状态管理器 原理是集中式储存管理
state储存数据
getters从state派生的数据,相当于state的计算属性
mutations 提交更新数据的方法,一般不做异步
actions 处理异步请求
modules 模块化vuex,可以让每一个模块拥有自己的state、mutation、actions、getters
四个语法糖对象 mapState mapGetters mapActions mapMutations
dispatch 异步操作 取数据 this.$store.dispatch('mutations方法名',值)
commit 同步操作 取数据 this.$store.commit('mutations方法名',值)
十一、路由模式
vue-router使用的hash模式,带#开发中默认使用这个模式,原理onhashchange事件,只能改变#后面的url片段
history不带#,怕刷新,刷新会出现404 如果用户考虑url的规范,就需要使用history模式
功能:在app中有分享页面,有的app里面url不允许带#,这个时候就要使用history模式,解决404需要后端人员配置一下重定向到首页路由,切换路由模式,在router里面的index.js配置mode:'history',不加默认是hash
十二、axios,ajax,fetch
ajax 异步的JavaScript和XML asynchronous 创建AJAx对象,发出http请求,接收服务器传回的数据 更新网页数据
1.本身是针对MVC的编程,不符合现在前端MVVM的浪潮
2.基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案 XML HTTP Request
3.使用ajax需要引入整个jQuery,jQuery整个项目太大,影响性能
fetch
1.符合关注分离,没有将输入输出和用事件来跟踪的状态混杂在一个对象里
2.更好更方便的写法
3.脱离了XHR,是ES规范里新的实现方式
4.fetch只对网络请求报错,对400,500都当做成功的请求,需要封装处理
5.fetch默认不会带cookie,需要添加配置项
6.fetch没有办法原生监测请求的进度,而XHR可以
axios 基于ajax和promise封装的
1.从node.js创建http请求
2.支持Promise API
3.拦截请求和响应
4.自动转换JSON数据
5.客户端支持防止CSRF/XSRF
6.提供了一些并发请求的接口
十三、并发请求
axios.all()的目的是批量发送请求,等所有请求都有返回时,再执行统一的回调
axios.all()里面写方法数组
axios.spread(回调)
十四、拦截器
请求拦截器 axios.interceptors.request.use()在请求之前判断是否有token,如果存在,则在请求头加上token,然后在请求
响应拦截器 axios.interceptors.response.use()在收到响应后进行一些操作,例如在服务器返回登录状态失效,需要重新登录的时候跳转到登录页
十五、守卫函数
全局守卫:是指路由实例上直接操作的钩子函数,特点是所有路由配置的组件都会触发,直白点就是触发这些钩子函数
beforeEach((to,from,next)=>{}) to->Route即将进入的目标,路由对象;from->当前正要离开的路由
next执行resolve钩子,执行效果依赖next方法的调用参数 判断当前页面是否有token
beforeResolve((to,from,next))
afterEach((to,from)=>{写操作})to:进入到哪个路由,from从哪个路由离开 登录时,验证密码账号正确以后,
弹出是否到某一页,点击确认后,再跳转
局部路由守卫:指在组件呢执行的钩子函数,类似于组件内的生命周期,相当于配置路由的组件添加的生命周期钩子函数
beforeRouteEnter((to,from,next))
beforeRouteUpadate((to,from,next))
beforeRouteLeave((to,from,next))
路由守卫:是指在单个路由配置的时候也可以设置的钩子函数
beforeEnter((to,from,next)=>{})
十六、v-if 和v-show有什么区别
v-if是惰性的,true变为false则元素销毁,false变为true则元素会被重建 条件很少改变,使用v-if
v-show 它只是对css display属性的切换 频繁切换使用
十七、图片懒加载
图片懒加载 使用 vue-lazyload插件 在img里面设置v-lazy
十八、vue性能优化
路由懒加载
不要在模板中写复杂的表达式
慎用watch尤其是deep
合理的使用v-if/v-show
十九、路由命名的好处?
在routers配置路由名称的时候给路由定义不同的名字,这样做的好处就是可以在使用router-link
的to属性跳转路由的时候传一个对象从而实现与router.push一样的效果
二十、Data为什么要return
因为不使用return包裹的数据会在项目的全局可见,会造成变量污染
使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
二十一、父子组件传值
父给子传:父组件调用子组件的地方,添加一个自定义的属性名,属性的值就是你要传给子组件的值。
在子组件定义的地方,添加一个props属性,最基本的写法为数组,数组内部写上自定义的属性名,
就可以在子组件直接通过{{自定义的属性名}}得到父组件传递的值
子给父传:子组件内部通过this.$emit('自定义事件名,传递的数据)把值传递出去,
父组件在调用子组件的地方,通过@自定义事件名=“父组件的方法”,父组件实现方法,它的参数就是子组件传递过来的值
兄弟组件传值:中央事件总线 const bus = new Vue(),
需要数据的地方 监听自定义事件即可 bus.$on('自定义事件',(data) => {})
需要传递数据的地方 执行自定义事件即可 bus.$emit('自定义时间',传递的值),先监听,后发送。
二十二、Vue(react) 中 key的作用
React和vue都实现了虚拟DOM 虚拟DOM有一套diff算法,而key就是用来给每个节点做一个唯一标识,
Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。所以其作用主要就是为了高效的更新虚拟DOM
二十三、Vue.js的$watch方法中,参数immediate的作用是什么?
首先,watch是一个对象,既然是对象就包含键值。
Watch中,键就是你要监控的家伙。
值可以是函数:就是当你监控的家伙变化时,需要执行的函数,这个函数有两个形参,第一个是当前值,第二个是变化后的值。
值也可以是函数名:不过这个函数名要用单引号来包裹。
第三种情况,值是包括选项的对象:选项包括有三个。
1.第一个handler:其值是一个回调函数。即监听到变化时应该执行的函数。
2.第二个是deep:其值是true或false;确认是否深入监听。(一般监听时是不能监听到对象属性值的变化的,
数组的值变化可以听到。)
3.第三个是immediate:其值是true或false;确认是否以当前的初始值执行handler的函数。
immediate如果为true 代表如果在 wacth 里声明了之后,就会立即先去执行里面的handler方法