侧边栏壁纸
  • 累计撰写 29 篇文章
  • 累计收到 1 条评论

vue

admin
2022-06-14 / 0 评论 / 18 阅读 / 正在检测是否收录...

问题

  1. Vue是单页面应用吗?
  2. Import和require?
  3. 路由懒加载以及具体如何实现?
  4. vue图片懒加载以及js实现懒加载的原理?
  5. V-bind,v-model区别?
  6. Vue2.0双向绑定原理和缺陷?
  7. Vue3.0实现双向数据绑定的方法?
  8. 路由导航守卫?
  9. HashRouter 和 HistoryRouter的原理和区别?
  10. 组件之间通信方式?
  11. 异步加载在mouted还是created?
  12. Vue的生命周期?
  13. Keep-alive组件?
  14. http和tcp的Keepalive?
  15. 父子组件生命周期函数调用顺序?
  16. 既然函数是引用类型,为什么 vue 的 data 还是可以用函数?
  17. $nextTick?
  18. V-if v-show 异同?
  19. Vuex?
  20. 首页白屏如何解决?
  21. 路由跳转和location.href的区别?
  22. Computed和watch区别?
  23. 混入?
  24. Vue提升性能的几种办法?
  25. 虚拟DOM和diff算法?
  26. 如何进行路由跳转?
  27. Push和replace区别?
  28. 路由跳转的时候所带的参数params和query参数区别?
  29. 编程式导航跳转到当前路由(路由未变的跳转),会报错的解决办法?
  30. 如果params的数据是’’,无法跳转如何解决?
  31. 路由组件能不能传递props数据?

答案:
Vue是单页面应用
单页面应用是指公共资源仅加载一次,页面加载只发送一次请求,直接把所有需要的html,css,js都加载完毕,后续的数据更新与交互是通过路由跳转和发送ajax请求来完成的。优点是页面跳转很快,只是路由跳转而没有发送http请求,缺点是首屏加载时间太长和seo效果差。
优点:交互体验好,页面显示比较流畅。 前后端分离 服务器压力小
缺点:首屏加载慢 不利于SEO

Import和require
Require是AMD规范,import是es6的语法标准
Require运行的时候调用,所以说可以放在任何地方用,import是编译的时候调用,必须放在开头的位置
两者都是模块化的体现
Import和require会返回一个promise对象

路由懒加载
Vue是单页面应用,如果没有懒加载会导致运用webpack打包后文件变得很大,造成进入首页时需要加载的东西很 多时间过长,则会出现长时间的白屏,不利于用户体验,懒加载可以将页面进行划分,需要的时候加载页面,能够有效分担压力,减少页面加载用的时间

路由懒加载的办法
Component写路由名字的时候利用import或者require,由于两者是返回一个promise函数,所以说vue router只会在第一次进入这个页面的时候才会获取函数,然后使用缓存数据

图片懒加载--vue-lazyload
先把img标签中的src设置成同一张图片(像素较低的),然后将其真正的图片地址存储在img标签的自定义属性之中,当js监听到该图片元素进入可视窗口的时候,在把自定义属性中的地址存储到src属性中。
实现方式, vue的话直接用插件可以定义默认状态图片和失败状态的图片
Js原生的话需要监听页面的滚动,每次页面滚动都会获取可视区域的高度,最后在对图片到页面的高度与可视高度与滑动高度的大小进行比较,当图片出现在可视窗口内的时候进行属性的替换。

V-bind,v-model区别
V-bind单向数据绑定,数据只能从data流向页面。
形式:v-bind:href=“xxx” xxx改变页面的url也会改变
v-model双向数据绑定,修改页面数据后台数据也会变。(只用在ipnut,textarea,select)
v-model = V-bind + oninput事件 @input="sth = $event.target.value"

Vue2.0双向绑定原理和缺陷?
采用数据劫持和发布订阅模式的方式,通过object.defineProperty()来劫持各个属性的setter,getter
缺陷
Vue实例创建后,无法检测到对象属性的新增或者删除(object.defineProperty只能劫持到对象的属性),只能追踪到是否被修改--------创建一个vue实例的时候,会遍历所有的dom对象,并给每个数据增加get和set。Get和set 可以观察数据的更改和更新数据。但是在vue实例创建之后在添加或删除一个属性,这个属性就没有get和set
不能监听数组的变化---------实现数组的响应式是对数组的部分方法进行了重写实现的,但是只重写了push/pop/shift/unshift/splice/sort/reverse,其他的方法对数组进行改写检测不到。

Vue3.0实现双向数据绑定的方法
通过proxy实现,proxy--在目标对象之前架设一层拦截,外界对该对象的访问,都必须先通过这层拦截,因此可以对外界的访问进行过滤和改写。
优点:可以利用proxy来处理一些非核心逻辑(如读取修改属性之前做验证等操作)
可以劫持整个对象,并返回一个新对象 有13种劫持操作

路由导航守卫
步骤:先实例化一个VueRouter对象,把所有的路由组件都配置在里面
主要是用于路由跳转的时候进行的一系列操作
分类:全局前置守卫(router.beforeEach)--导航开始的时候调用
全局解析守卫(router.beforeResolve)---指所有组件内守卫和异步路由组件解析后,但是导航还没有确认之前的
全局后置守卫(router.afterEach)--主要用于分析,更改页面标题等
路由独享守卫(全局守卫一致,不过没有router. 了)---定义在每个路由的配置上
组件内守卫(beforeRouterEnter,...Update,...Leave)---VueRouter路由组件内定义(只针对当前组件的路由跳转,分为进入、更新、离开)
beforeRouterEnter--是在渲染该组件前,组件实例创建之前的,所以不能获取this
beforeRouterUpdate--当前路由改变,但是该组件被复用的时候调用,可以访问this
beforeRouterLeave--在导航离开渲染该组件的对应路由的时候调用,可以访问this

HashRouter 和 HistoryRouter的原理和区别
他们都是url改变的时候能够监听的到
HashRouter--原理是利用了hashchange事件,能够在window监听hash的变化,vue-roter默认是hash模式--这种模式利用url的hash来模拟一个完整的url,就是项目中的#,#后面的hash发生变化的时候,不会导致浏览器给服务器发请求,并且会触发hashchange,可以通过监听hash值的变化来实现页面的更新。hash模式会创建hashHistory对象,访问不同的路由组件的时候会hashHistory.push(新路由放到栈顶)和hashHistory.replace记录浏览历史
HistoryRouter--利用pushState(),replaceState()结合window.popstate(监听前进后退)实现的,pushState改变url地址不发请求,replaceState可以读取历史记录栈,还可以对浏览器的历史记录修改
区别
pushState设置的url可以是当前同源的所有url,而hash只能修改#后面的
pushState新旧url可以一致,hash的则必须不一样
pushState可以通过stateObject添加任意类型数据记录,hash只可以短字符串
pushState可以设置title属性
pushState兼容ie10,hash ie8
pushState需要后端配合将所有的访问都指向index.html,否则刷新会404
Hash模式不会请求服务器

HashRouter 和 HistoryRouter的原理和区别
他们都是url改变的时候能够监听的到
HashRouter--原理是利用了hashchange事件,能够在window监听hash的变化,vue-roter默认是hash模式--这种模式利用url的hash来模拟一个完整的url,就是项目中的#,#后面的hash发生变化的时候,不会导致浏览器给服务器发请求,并且会触发hashchange,可以通过监听hash值的变化来实现页面的更新。hash模式会创建hashHistory对象,访问不同的路由组件的时候会hashHistory.push(新路由放到栈顶)和hashHistory.replace记录浏览历史
HistoryRouter--利用pushState(),replaceState()结合window.popstate(监听前进后退)实现的,pushState改变url地址不发请求,replaceState可以读取历史记录栈,还可以对浏览器的历史记录修改
区别
pushState设置的url可以是当前同源的所有url,而hash只能修改#后面的
pushState新旧url可以一致,hash的则必须不一样
pushState可以通过stateObject添加任意类型数据记录,hash只可以短字符串
pushState可以设置title属性
pushState兼容ie10,hash ie8
pushState需要后端配合将所有的访问都指向index.html,否则刷新会404
Hash模式不会请求服务器

异步加载在mouted还是created
两者都可以,更多是在created中,因为能够更快的获取到服务端的数据,减少页面加载的时间,created加载的早一点。但是在created中dom元素还没有加载出来,如果需要操作dom的话放在mounted中。

Vue的生命周期
Vue 实例从创建到销毁的过程,就是生命周期。
第一次页面加载会触发哪几个钩子?
beforeCreate , created , beforeMount ,mounted 这几个钩子
beforeCreate:创建前,此阶段为实例初始化之后,this指向创建的实例,此时的数据观察事件机制都未形成,不能获得DOM节点。
data,computed,watch,methods 上的方法和数据均不能访问。
可以在这加个loading事件。
created:创建后,此阶段为实例已经创建,完成数据(data、props、computed)的初始化导入依赖项。
可访问 data computed watch methods 上的方法和数据。
初始化完成时的事件写在这里,异步请求也适宜在这里调用(请求不宜过多,避免白屏时间太长)。
可以在这里结束loading事件,还做一些初始化,实现函数自执行。
未挂载DOM,若在此阶段进行DOM操作一定要放在Vue.nextTick()的回调函数中。
beforeMount:挂载前,虽然得不到具体的DOM元素,但vue挂载的根节点已经创建,下面vue对DOM的操作将围绕这个根元素继续进行。
beforeMount这个阶段是过渡性的,一般一个项目只能用到一两次。
mounted:挂载,完成创建vm.$el,和双向绑定
完成挂载DOM和渲染,可在mounted钩子函数中对挂载的DOM进行操作。
可在这发起后端请求,拿回数据,配合路由钩子做一些事情。
beforeUpdate:数据更新前,数据驱动DOM。
在数据更新后虽然没有立即更新数据,但是DOM中的数据会改变,这是vue双向数据绑定的作用。
可在更新前访问现有的DOM,如手动移出添加的事件监听器。
updated:数据更新后,完成虚拟DOM的重新渲染和打补丁。
组件DOM已完成更新,可执行依赖的DOM操作。
注意:不要在此函数中操作数据(修改属性),会陷入死循环。
activated:在使用vue-router时有时需要使用来缓存组件状态,这个时候created钩子就不会被重复调用了。
如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发。
deactivated:组件被移除时使用。
beforeDestroy:销毁前,
可做一些删除提示,如:您确定删除xx吗?
destroyed:销毁后,当前组件已被删除,销毁监听事件,组件、事件、子实例也被销毁。
这时组件已经没有了,无法操作里面的任何东西了。

Keep-alive组件
l4dwoy5s.png
保存组件状态而不销毁,返回后仍在选本状态,避免了重复渲染。

http和tcp的Keepalive
状态保持或者重用机制,一条连接的建立不会被中断

父子组件生命周期函数调用顺序
执行顺序:
父组件开始执行到beforeMount 然后开始子组件执行,最后是父组件mounted。
如果有兄弟组件,父组件开始执行到beforeMount,然后兄弟组件依次执行到beforeMount,然后按照顺序执行mounted,最后执行父组件的mounted。

当子组件挂载完成后,父组件才会挂载。
当子组件完成挂在后,父组件会主动执行一次beforeUpdated/updated钩子函数(仅首次)
父子组件在data变化中是分别监控的,但是更新props中的数据是关联的。
销毁父组件时,先将子组件销毁后才会销毁父组件。
兄弟组件的初始化(mounted之前)是分开进行,挂载是从上到下依次进行
当没有数据关联时,兄弟组件之间的更新和销毁是互不关联的

既然函数是引用类型,为什么 vue 的 data 还是可以用函数?
Js中只有函数才会构成作用域,对象的{}和if的{}不构成,data是一个函数的时候每个组件实例都可以有自己的作用域,互不影响

Vue中哪个生命周期内调用异步请求
Created beforeMount mounted
推荐在Created的钩子函数中调用异步请求
Created能更快的获取到服务器端的数据,减少页面加载时间

$nextTick
由于vue dom更新是异步的,所以修改数据的时候不会立马更新,而是通过监听数据的变化,并缓存在同一事件循环之中,当前事件循环所有数据变化完成后在统一进行更新数据。使用$nextTick就是为了获取页面更新后的dom和数据。
原理:运用宏任务和微任务定义一个异步的方法。

V-if v-show 异同
l4dwqpau.png
l4dwqs2y.png

Vuex--vue中的状态管理工具
l4dwr0it.png
Actions:修改异步请求(使用commit提交) 第一个默认参数是{commit}
mutations:同步更改state状态 第一个默认参数是state
getter:对state中的数据进行过滤

首页白屏如何解决
路由懒加载 cdn加速 开启vue服务渲染模式 减少打包体积删除不必要的代码
也可以添加loading效果,增强用户体验

路由跳转和location.href的区别?
路由跳转静态调整不刷新页面,location.href刷新页面

Computed和watch区别
Computed里的属性名是自定义的,可以监听一个或者多个所依赖的数据项,watch一次只能监听一个属性,这个属性的函数有两个参数,一个新值一个旧值
Computed的自定义属性不能与data里面的重复,watch则必须是已经存在的属性
Watch允许异步操作以及设置中间状态,Computed不可以

混入 mixin 分发vue组件中可复用的功能(和公共组件差不多)
1 定义一个混入对象(包含任意组件选项,例如created,methods等)
2 定义一个使用混入对象的组件
Var Component = Vue.extend({
Mixins:[定义的混入对象] })
3 var component = new Component()
4 此时component 这个组件就拥有了混入对象的所有组件选项
5 当使用混入对象的组件与混入对象有同名选项的时候会进行合并,本身的优先
6 混入对象的钩子在组件自身钩子之前调用

Vue提升性能的几种办法?
懒加载 少用v-if 组件拆分,组件内部的运行不会影响其他外部组件 使用keep-alive切换路由 v-for加key

虚拟DOM和diff算法
虚拟dom 通过js的object对象模拟dom中的节点,然后再通过特定的render方法将其渲染成真实的dom节点,最后通过appendChild()添加到页面中去,比操作真实dom节点更加节省性能。
Diff算法
对比新老虚拟DOM,记录变化,将变化部分更新到视图上。对操作前后的dom树同一层的节点进行对比,然后一层一层的对比下去。当一层节点有很多的时候也是会一个一个的对比,但是如果增加了一个key,diff算法就能够更快的识别更改的节点,并对其进行更改。
Vue列表为什么加key
Key可以标识组件的唯一性,区别各个组件的key是为了可高效的更新虚拟DOM

如何进行路由跳转?
声明式导航和编程式导航。声明式导航就是router-link,编程式导航就是this.$router.push|replace。如果在进行路由跳转的时候还有其他事情要做,就可以使用编程式导航,因为是在方法中定义的。

Push和replace区别,push能够记住历史,repalce不能记住(登陆后后退不能返回到登录页面)
路由跳转的时候所带的参数params和query参数区别
params参数:路由需要占位,属于URL当中一部分。 query参数,路由不需要占位,写法类似于ajax当中query参数。query传参需要配置path,params需要配置name,在params中配置path无效。query在路由配置中不需要设置参数,params必须设置。query传递的参数会显示在地址栏。params传参刷新后无效,query会保存传过来的值。
编程式导航跳转到当前路由(路由未变的跳转),会报错,解决办法重写vue原型上的push和replace

如果params的数据是’’,无法跳转如何解决?指定params参数值为undefined

路由组件能不能传递props数据?可以,将query参数或params参数转换成props传递
props: (route)=>({keyword1:route.params.keyword, keyword2: route.query.keyword })

控制某个组件的显示和隐藏(即大部分情况下要用到,偶尔用不到)
在路由的配置中利用meta配置和v-show实现。在使用组件的时候使用v-show对meta判断

0

评论 (0)

取消