1、Vue2.x组件通信有哪些方式

1. 父子通信

  • 父向子传递数据是通过props子向父是通过 events( $emit
  • 通过父链 / 子链也可以通信( $parent / $children);
  • ref 也可以访问组件实例
  • provide / inject API;
  • $attrs/$listeners

2. 兄弟通信BusVuex

3. 跨级通信BusVuexprovide / inject API$attrs/$listeners

2、Vue 中的 computed 和 watch 的区别在哪里

  • 计算属性computed :

    1. 支持缓存 ,只有依赖数据发生改变,才会重新进行计算
    2. 不支持异步 ,当computed内有异步操作时无效,无法监听数据的变化
    3. computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是***基于data中声明过或者父组件传递的props中的数据通过计算得到的值***
    4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
    5. 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法
  • 侦听属性watch:

    1. 不支持缓存,数据变,直接会触发相应的操作;
    2. watch支持异步
    3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值
    4. 当一个属性发生变化时,需要执行对应的操作;一对多
    5. 监听数据必须是***data中声明过或者父组件传递过来的props中的数据***,当数据变化时,触发其他操作,函数有两个参数:
      • immediate:组件加载立即触发回调函数执行
      • deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用

3、组件中的data为什么是一个函数

在JavaScript中如果两个实例引用同一个对象,当其中一个实例的属性发生改变时,另一个实例属性也随之改变只有当两个实例拥有自己的作用域时,才不会相互干扰

组件中的data写成一个函数,数据以函数返回值的形式定义,这样***每次复用组件的时候,都会返回一份新的data***,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。如果单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了

4、Vue的性能优化

基础优化

  • 尽量减少data中的数据,data中的数据都会增加gettersetter,会收集对应的watcher
  • v-ifv-for不能连用
  • 如果需要使用v-for给每项元素绑定事件时使用事件代理
  • SPA 页面采用keep-alive缓存组件
  • 在更多的情况下,使用v-if替代v-show
  • key保证唯一
  • 使用路由懒加载、异步组件
  • 防抖、节流
  • 第三方模块按需导入
  • 长列表滚动到可视区域动态加载
  • 图片懒加载

SEO优化

  • 预渲染
  • 服务端渲染SSR

打包优化

  • 压缩代码
  • Tree Shaking/Scope Hoisting
  • 使用cdn加载第三方模块
  • 多线程打包happypack
  • splitChunks抽离公共文件
  • sourceMap优化

用户体验

  • 骨架屏
  • PWA

5、Vue的双向绑定数据的原理

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

  • Model层 -> View层:setter
  • View层 -> Model层:事件
  • 替代方案:单项绑定 v-bind:value + 事件 v-on:input

6、对 MVC、MVVM的理解

MVCM:Model 数据层,V:View 视图层,C:Controller 控制层

MVC模式是单项绑定,即model绑定到view,当我们用js代码更新model时,view就会自动更新

image

  • model负责数据保存,与后端数据进行同步
  • controller负责业务逻辑,根据用户行为对model数据进行修改
  • view负责视图展示,将model中的数据可视化出来
  • 缺点:强行分层,一个小小的功能都必须经过这么一个流程,并不灵活

MVPM:Model 数据层,V:View 视图层,P:Presenter 控制层

MVP 架构模式是 MVC 的改良模式(改进 Controller, 把 Model 和 View 完全隔离开)

  • model负责数据保存,与后端数据进行同步
  • Presenter负责和model及view进行双向交互
  • view负责视图展示,将model中的数据可视化出来
  • 缺点:相对于MVC更不灵活,虽然分离了model和view,但是导致Presenter体积变大,难以维护。

MVVMM:Model 数据层,V:View 视图层,VM:ViewModel 控制层

由 MVP 模式演变而来

  • model负责数据保存,与后端数据进行同步
  • viewModel通过响应式机制自动响应Model数据变化,通过更新策略自动将数据变化转换为视图更新,通过事件监听响应View中用户交互修改的Model数据
  • view负责视图展示,将model中的数据可视化出来
  • 优点
    • 减少大量DOM操作代码
    • 保持View和Model的松耦合
    • 便于维护
    • 开发效率高

总结

  • 这三者都是框架模式,它们设计的目标都是为了解决Model和View的耦合问题
  • MVC模式出现较早主要应用在后端,如Spring MVCASP.NET MVC等,在前端领域的早期也有应用,如Backbone.js。它的*优点是分层清晰,缺点是数据流混乱,灵活性带来的维护性问题
  • MVP模式在是MVC的进化形式, Presenter作为中间层负责MV通信, 解决了两者耦合问题,但P层过于臃肿会导致维护问题。
  • MVVM模式在前端领域有广泛应用,它不仅解决MV耦合问题,还同时解决了维护两者映射关系的大量繁杂代码和DOM操作代码,在提高开发效率、可读性同时还保持了优越的性能表现

7、vue父组件向子组件传递数据

通过props

8、v-if 和 v-show 区别

  • 共同点:v-ifv-show 都可以动态地显示DOM元素
  • 区别
    • 手段:

      v-if 是动态的向DOM树内添加或者删除DOM元素

      v-show 是通过设置DOM元素的display样式属性控制显隐

    • 编译过程:

      v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;

      v-show只是简单的基于css切换

    • 编译条件:

      v-if惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载);

      v-show在任何条件下,然后被缓存,而且DOM元素保留;

    • 性能消耗:

      v-if 有更高的切换消耗

      v-show 有更高的初始渲染消耗

    • 使用场景:

      v-if 适合运营条件不大可能改变

      v-show 适合频繁切换

9、vue生命周期的理解

生命周期函数(钩子函数):在生命周期特定的时间自动执行的函数

  • 生命周期阶段
    • 创建阶段:Create

      • beforeCreate():初始化完成,但未往实例添加属性

        应用:可以在这加个 loading 事件

      • created():往实例添加属性完成,但 DOM 还未生成

        应用:在这结束 loading,还做一些初始化,实现函数自执行

    • 挂载阶段:Mount

      • beforeMount():可以获取节点,但数据未渲染

        应用:在这发起 ajax 请求,拿回数据,配合路由钩子做一些事情

      • mounted():实例挂载到 DOM 完成

        应用:节点操作

    • 更新阶段:Update

      • beforeUpdate():数据有更新但未更新节点
      • update():更新节点完毕
    • 销毁阶段:Destroy

      • beforeDestroy()
      • destroyed():执行 destroy()后,不会改变已生成的 DOM 节点,但后续就不再受 vue 控制了

        应用:清除定时器、延迟器、取消 ajax 请求等

10、解释单向数据流和双向数据绑定

  • 单向数据流:指数据的改变只能从一个方向修改

    例:子组件不能直接改变父组件的传入的数据。但是如果父组件改变相应的数据,子组件的数据也会发生相应的改变。

  • 双向数据绑定

    由MVVM框架实现,MVVM的组成:View,ViewModel,Model。其中View 和 Model不能直接通信,要通过ViewModel来进行通信。

    • Model部分数据发生改变时,由于vue中Data Binding将底层数据和Dom层进行了绑定,ViewModel通知View层更新视图
    • 当在视图View数据发生变化也会同步到Model中。View和Model之间的同步完全是自动的,不需要人手动的操作DOM。

11、对比 jQuery ,Vue 有什么不同

  • jquery:依赖DOM元素的值

    • 使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作
    • 和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的
  • Vue:是一个精简的MVVM

    • 对数据进行操作不再需要引用相应的DOM对象
    • 通过双向数据绑定把 View 层和 Model 层连接了起来,通过对数据的操作就可以完成对页面视图的渲染。

12、Vue 中怎么自定义指令

指令的注册方式分为两种:一是全局注册,二是局部注册

  • 全局注册(推荐)
    Vue.directive('name', {`options`})
  • 局部注册
    directives: {
        'name': {`options`}
    }

具体的实现方式

  • Vue 提供了自定义指令的几个钩子函数:

    updatecomponentUpdated 钩子函数之外,每个钩子函数都含有 elbindingvnode 这三个参数。

    • bind:指令第一次绑定到元素时调用,只执行一次。
    • inserted:被绑定的元素,插入到父节点的 DOM 中时调用。
    • update:组件更新时调用。
    • componentUpdated:组件与子组件更新时调用。
    • unbind:指令与元素解绑时调用,只执行一次。
    • 参数
      • el 指令所绑定的元素,可以用来直接操作 DOM
      • binding 一个对象,包含以下案例中的属性
      • vnode
      • oldVnode

        仅在update 和 componentUpdated 钩子中可用

13、Vue 中 key 的作用

  • v-if中的key

    管理可复用的元素:声明其中的可复用的元是完全独立的——不要复用它们”

  • v-for中的key

    给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素。

14、Vue 的核心思想是什么

数据驱动、组件化

  • 数据驱动

    数据(model)改变 -> 视图(view)自动更新

Vue中,Directives对view进行了封装,当model里的数据发生变化时,Vue就会通过Directives指令去修改DOM。
同时也通过DOM Listener实现对视图view的监听,当DOM改变时,就会被监听到,实现model的改变,实现数据的双向绑定。
  • 组件响应原理

    Vue 遍历实例的 data选项所有的属性,使用 Object.defineProperty 把这些属性全部转为 getter/setter

  • 组件化

    实现了扩展HTML元素,封装可重用的代码

    • 页面上每个独立的可视/可交互区域视为一个组件
    • 每个组件对应一个工程目录,组件所需要的各种资源在这个目录下就近维护
    • 页面不过是组件的容器,组件可以嵌套自由组合形成完整的页面。

15、Vue 等单页面应用的优缺点

  • 单页面应用(SPA)

    指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。

    • 优点:

      1. 用户体验好,快,内容的改变不需要重新加载整个页面,对服务器压力较小
      2. 前后端分离,比如vue项目
      3. 完全的前端组件化,前端开发不再以页面为单位,更多地采用组件化的思想,代码结构和组织方式更加规范化,便于修改和调整;
    • 缺点:

      1. 首次加载页面的时候需要加载大量的静态资源,这个加载时间相对比较长
      2. 不利于 SEO优化,单页页面,数据在前端渲染,就意味着没有 SEO。
      3. 页面导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自 己建立堆栈管理)
  • 多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新。

16、子组件向父组件传递事件?

$emit方法

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

在组件中的style标签里面加上scoped

18、如何获取dom?

使用Vue内置属性:$refs

    <div ref="domName"></div>
    
    用法:this.$refs.domName

19、说出几种vue当中的指令和它的用法?

v-model双向数据绑定;
v-for循环;
v-if / v-show 显示与隐藏;
v-on事件;
v-once: 只绑定一次。

20、为什么使用key?

使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。
作用主要是为了高效的更新虚拟DOM

21、渐进式框架的理解

主张最少;可以根据不同的需求选择不同的层级;

22、Vue中双向数据绑定是如何实现的?

vue 双向数据绑定是通过 数据劫持结合发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变

  • 核心:关于VUE双向数据绑定,其核心是Object.defineProperty()方法。

23、单页面应用和多页面应用区别及优缺点

  • 单页面应用(SPA)

    指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中
    但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。

    • 优点用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小前后端分离页面效果好会比较炫酷(比如切换页面内容时的专场动画)。
    • 缺点不利于seo导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理); 初次加载时耗时多页面复杂度提高很多。
  • 多页面(MPA)

指一个应用中有多个页面,页面跳转时是整页刷新

24、v-if和v-for的优先级

v-ifv-for 一起使用时,v-for的优先级更高

不推荐v-if和v-for同时使用。如果v-if和v-for一起用的话,vue中的的会自动提示v-if应该放到外层去

25、vue常用的修饰符

  • .stop防止事件冒泡,等同于JavaScript中的event.stopPropagation();
  • .prevent防止执行预设的行为,等同于JavaScript中的event.preventDefault()(如果事件可取消,则取消该事件,而不停止事件的进一步传播);
  • .capture:与事件冒泡的方向相反,事件捕获由外到内
  • .self:只会触发自己范围内的事件,不包含子元素;
  • .once:只会触发一次

26、Vue-router 使用params与query传参有什么区别

$router : 是路由操作对象,只写对象
$route : 路由信息对象,只读对象

  • query传递参数

    query可以使用name来传参,也可以使用path

//query传参,使用name跳转
this.$router.push({
    name:'xxx',
    query: {
        id:'20180822',
    }
})

//query传参,使用path跳转
this.$router.push({
    path:'/xxx',
    query: {
        id:'20180822',
    }
})

//query传参接收
 this.$route.query.id;
  • params传递参数

    params传参只能使用name进行引入

//路由格式
{
path: '/xxx/:id',
name: 'xxx',
component: () => import('@/view/xxx')

//params传参 使用name
this.$router.push({
  name:'xxx',
  params: {
    id:'20180822',
  }
})

//params接收参数
this.$route.params.id ;
  • 总结
    • query相当于get请求,页面跳转的时候,可以在地址栏看到请求参数,
    • params相当于post请求,参数不会再地址栏中显示

27、分别简述computed和watch的使用场景

  • computed:

    一个属性受多个属性影响的时候就需要用到computed
    最典型的栗子: 购物车商品结算的时候

  • watch:

    一条数据影响多条数据的时候就需要用watch
    栗子:搜索数据

28、在Vue中发起Ajax请求

使用:axios

29、v-on可以监听多个方法吗

可以, 在v-on中使用{ }:
<input type="text" v-on="{ input:onInput,focus:onFocus,blur:onBlur,... }">

30、什么是Vue-loader

1.  vue-loader是webpack的加载器,允许以单文件组件(SFC)的格式创作Vue组件
2.  允许对Vue组件的每个部分使用其他webpack加载器
3.  允许.vue文件中的自定义块可以应用自定义加载程序链,简单来说就是可以解析.vue文件
4.  处理在模块依赖项中引用的静态资源
5.  模拟每个组件的范围CSS
6.  在开发过程中保持热加载(同步更新)

31、$nextTick的使用

当你修改了data里的值然后马上获取这个dom元素的值,是不能获取到更新后的值
需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。

32、用过插槽吗?用的是具名插槽还是匿名插槽

插槽solt:父组件的数据和子组件进行内容互相传递的工具

  • 父组件 -> 子组件:插槽

    使用 slot 插槽标签,可以使用父组件传来的内容进行展示,至于在哪里展示 由子组件决定

    • 默认插槽 default:<slot/>
    • 具名插槽:
      • 子组件使用<slot name="xxx" />
      • v-slot:父组件在定义时使用<tempalte v-slot:xxx></tempalte>
  • 子组件 -> 父组件:作用域插槽

    使用slot-scope 进行数据的传递,父组件引用子组件中的数据

    • 子组件在<slot/>里定义数据:
      <slot name="xxx" :msg="msg" :username="username" />

    • 父组件使用<tempalte v-slot:xxx="scope"></tempalte>接收数据

      scope:保存 xxx 插槽中 props 数据

33、assets和static文件夹的区别

assets和static两个都是存放静态资源文件。项目中所需要的资源文件图片、字体图标、样式文件等都可以放在这两个文件下。

  • 区别:

    • assets:在项目打包时,会将assets中放置的静态资源文件进行打包上传,所谓打包简单点可以理解为压缩体积,代码格式化。而压缩后的静态资源文件最终也都会放置在static文件中跟着index.html一同上传至服务器
    • static:不会打包压缩格式化等,而是直接进入打包好的目录,直接上传至服务器
  • 建议将项目中template需要的样式文件js文件等都可以放置在assets中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css等文件可以放置在static中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。

34、请你说一下vue中create和mount的区别

生命周期是否获取dom节点是否可以获取data是否获取methods
beforeCreate
created
beforeMount
mounted
  • beforecreate阶段

    实例尚未被初始化,对data、methods或文档节点的调用现在无法得到正确的数据。

  • created阶段

    实例已经被初始化,但是还没有挂载至$el*上,无法获取到对应的节点,可以获取到data与methods中的数据

  • beforeMount阶段

    与created阶段类似,节点尚未挂载,可以获取到data与methods中的数据。

  • mounted阶段

    完成了dom与css规则树的render,并完成对render tree进行了布局,vue的template成功挂载在$el中,可以调用节点

35、子组件中是否可以修改props,如果想修改的话如何修改

Vue的props是单向下行绑定:所以子组件中直接不可以修改父组件传入props

  • .sync语法糖:可以对props进行“双向绑定”
<text-document :title.sync="doc.title"></text-document>

// 当子组件需要更新 title 的值时,它需要显式地触发一个更新事件:
// 使用$emit及默认update方法
this.$emit('update:title', newValue)

这样title的属性在子组件内部更新,父组件也能感知的到,实现了“双向绑定”。

36、Object.defineProperty有什么缺点

Object.defineProperty只能劫持对象的属性,从而需要对劫持的每个对象,进行属性遍历,如果属性值是对象,还需要深度遍历,性能消耗比较大。

37、引进组件的步骤

  1. 在template中引入组件;
  2. 在script的第一行用import引入路径;
  3. 用component中写上组件名称。

38、delete和Vue.delete删除数组的区别

  • delete:被删除的元素变成了 empty/undefined 其他的元素的键值还是不变
  • Vue.delete: 直接删除了元素,改变了元素的键值

39、SPA首屏加载慢如何解决

安装动态懒加载所需插件;使用CDN资源。

40、Vue-router跳转和location.href有什么区别

  • location.href:跳转刷新了页面

  • history.pushState():无刷新页面,静态跳转;

  • router.push():无刷新页面,静态跳转,使用了diff算法,实现了按需加载,减少了dom的消耗

  • 注意:router跳转和使用history.pushState()没什么差别的,因为vue-router就是用了history.pushState(),尤其是在history模式下。

41、vue slot

简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示、不显示、在哪个地方显示、如何显示,就是slot分发负责的活。

42、做管理系统项目 Vue和React 怎么选择

  • Angular的极限面向对象处理复杂业务非常舒适,但是对于轮子兄弟极其不友好,没有CDK你就只能抓瞎,一句话:高楼大厦,攀登不易。
  • React的Hooks有很强的Hacky精神,零星几个API,绝大部分需求皆可实现,一句话:步步为营,跬步千里。
  • Vue的API数量适中,基础设施完善,文档友好,概念与Angular和React都互通,一句话:百家之长,指哪打哪

43、Vuex的缺点

对于非大型单页应用,使用Vuex可能是繁琐冗余的。如果应用够简单,最好不要使用 Vuex。一个简单的 store 模式可以了。

44、对于vue项目是打包了一个js文件,一个css文件,还是有多个文件?

根据vue-cli脚手架规范,一个js文件,一个css文件。

45、Vue里面router-link在电脑上有用,在安卓上没反应怎么解决

Vue路由在Android有问题,babel问题,安装babel polypill插件解决。

46、Vue2中注册在router-link上事件无效解决方法

方法:使用@click.native。
原因:router-link会阻止click事件,.native指直接监听一个原生事件。

47、RouterLink在IE和Firefox中不起作用(路由不跳转)的问题

  • 方法一:只用a标签,不使用button标签;
  • 方法二:使用button标签和Router.navigate方法

48、axios的特点有哪些

  • 浏览器中创建XMLHttpRequests;
  • node.js创建http请求;
  • 支持Promise API;
  • 拦截请求和响应:axois.interceptors.request/response
  • 转换请求数据和响应数据:
  • 取消请求:axios.CancelToken.source()
  • 自动换成json。
  • axios中的发送字段的参数是data跟params两个,两者的区别在于params是跟请求地址一起发送的,data的作为一个请求体进行发送
    • params一般适用于get请求,data一般适用于post put delete 请求。

49、Vue深层次嵌套传值方法

Vuex

50、封装 vue 组件的过程

  1. 建立组件的模板,先把架子搭起来,写写样式,考虑好组件的基本逻辑。
  2. 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。
  3. 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。
  4. 封装完毕了,直接调用即可

51、params和query的区别

  • 用法:query可以用pathname来引入,params一定要用name来引入
  • 接收::query->this.$route.query.nameparams->this.$route.params.name
  • url地址显示:query更加类似于我们ajax中get传参会显示在url上,params则类似于post不会显示
  • 数据持久:query刷新不会丢query里面的数据,params刷新会丢失**params里面的数据。

52、vue初始化页面闪动问题

在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{{message}}的字样

  • 方法一:在css里加上[v-cloak] {display: none;}
  • 方法二:在根元素加上style="display: none;" :style="{display: 'block'}"

53、vue更新数组时触发视图更新的方法

push();pop();shift();unshift();splice(); sort();reverse()

54、vue常用的UI组件库

  • elementUI 饿了么
  • ant-design 蚂蚁金服
  • iView 腾讯
  • VantUI 有赞
  • VUX
  • Mint UI

55、vue修改打包后静态资源路径的修改

  • cli2版本:将 config/index.js 里的 assetsPublicPath 的值改为 ‘./’ 。
    build: {
    // ...
    assetsPublicPath: './',
    // ...
    }
  • cli3版本:在根目录下新建vue.config.js 文件,加上以下内容
    module.exports = {
        publicPath: '', // 相对于 HTML 页面(目录相同) 
    }

56、什么是 vue 生命周期?有什么作用?

  • 生命周期:每个Vue实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等
  • 作用:在vue生命周期过程中会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会

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

beforeCreate, created, beforeMount, mounted

58、简述每个周期具体适合哪些场景

  • 创建阶段:Create
    • beforeCreate():初始化完成,但未往实例添加属性

      应用:可以在这加个 loading 事件

    • created():往实例添加属性完成,但 DOM 还未生成

      应用:在这结束 loading,还做一些初始化,实现函数自执行

  • 挂载阶段:Mount
    • beforeMount():可以获取节点,但数据未渲染

      应用:在这发起 ajax 请求,拿回数据,配合路由钩子做一些事情

    • mounted():实例挂载到 DOM 完成

      应用:节点操作

  • 更新阶段:Update
    • beforeUpdate():数据有更新但未更新节点
    • update():更新节点完毕
  • 销毁阶段:Destroy
    • beforeDestroy()
    • destroyed():执行 destroy()后,不会改变已生成的 DOM 节点,但后续就不再受 vue 控制了

      应用:清除定时器、延迟器、取消 ajax 请求等

59、vue获取数据在哪个周期函数

一般 created/beforeMount/mounted 皆可.

60、对vue生命周期的理解?

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

  • 创建前/后:
    • beforeCreated阶段,vue实例的挂载元素$el数据对象data都undefined,还未初始化。
    • created阶段,vue实例的数据对象data有了$el还没有。
  • 载入前/后:
    • beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未渲染
    • mounted阶段,vue实例挂载完成,data.message成功渲染
  • 更新前/后:当data变化时,会触发beforeUpdate和updated方法
  • 销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

61、mvvm 框架是什么?

当视图改变同时更新模型层,当模型层改变也会同时更新视图层

62、vue-router 是什么?它有哪些组件

vue用来写路由一个插件。
组件:router-linkrouter-view

63、active-class 是哪个组件的属性?

vue-router模块的router-link组件的属性

64、Vue中ajax请求代码应该写在组件的methods中还是vuex的actions中?

如果请求回的数据在组件中公用率大,可以将请求放入Vuex的actions里,数据放在vuex的state里,方便复用
如果请求回的数据仅仅在某个的组件内使用,就放在组件里请求。

65、vuex有哪几种属性?

state => 基本数据(数据源存放地)
getters => 从基本数据派生出来的数据
mutations => 提交更改数据的方法同步
actions => 像一个装饰器方法,包裹mutations,使之可以异步
modules => 模块化Vuex

66、vue-router实现路由懒加载( 动态加载路由 )

  • 第一种:vue异步组件技术 =>异步加载,vue-router配置路由,使用vue的异步组件技术 ,可以实现按需加载,这种情况下一个组件生成一个js文件。
  • 第二种:路由懒加载(使用import)。
  • 第三种:webpack提供的require.ensure(),vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

67、vuex是什么?怎么使用?哪种功能场景使用它?

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

  • 使用
    1. 安装引用:npm i vuex
    import Vuex from "vuex";
    
    1. 使用
    Vue.use(Vuex);
    
    1. 实例化
    const store = new Vuex.Store({});
    
    1. 注入根实例
    new Vue({
      store,
    });
    
    1. 在组件中使用
    this.$store;
    

68、vue优点?

  • 轻量级框架只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
  • 简单易学国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
  • 双向数据绑定:保留了angular的特点,在数据操作方面更为简单
  • 组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势
  • 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
  • 虚拟DOM:dom操作是非常耗费性能的,不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
  • 运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。

69、在哪个生命周期内调用异步请求?

可以在钩子函数 created、beforeMount、mounted中进行调用,因为在这三个钩子函数中,data已经创建,可以将服务端端返回的数据进行赋值。

  • 推荐在 created 钩子函数中调用异步请求
    • 能更快获取到服务端数据,减少页面 loading 时间;
    • ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;

70、使用过 Vuex 吗

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

每一个 Vuex 应用的核心就是store(仓库)。store基本上就是一个容器,它包含着你的应用中大部分的状态 (state)

(1)Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

(2)改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

Vuex主要包括以下几个模块:

  • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
  • Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
  • Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
  • Action用于提交mutation,而不是直接变更状态,可以包含任意异步操作。
  • Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

71、介绍下vue单页面和多页面区别

  • 单页面首次加载缓慢,但是后面的加载优势就会超过多页面了。
  • 多页面则是首次加载快,但是后面每次都要进行加载。

vue比较适合做单页面的

72、虚拟 DOM 的优缺点

  • 优点:

    • 保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;
    • 无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;
    • 跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex(WeApp)开发等等。
  • 缺点:

    • 无法进行极致优化: 虽然虚拟 DOM+合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。

73、虚拟 DOM 实现原理?

  • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
  • diff 算法 — 比较两棵虚拟 DOM 树的差异;
  • pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

74、$NextTick 是做什么的

$nextTick是在下次 DOM 更新循环结束之后执行延迟回调,
在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM

75、Class 与 Style 如何动态绑定?

  • Class 可以通过对象语法数组语法进行动态绑定:

    • 对象语法:
     <div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>  
    data: {   
      isActive: true, 
      hasError: false 
    } 
    
    • 数组语法:
     <div v-bind:class="[isActive ? activeClass : '', errorClass]"></div> 
     data: {   
        activeClass: 'active', 
        errorClass: 'text-danger'
     } 
    
  • Style 也可以通过对象语法数组语法进行动态绑定:

    • 对象语法:
    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>  
    data: {
        activeColor: 'red',
        fontSize: 30 
    } 
    
    • 数组语法:
     <div v-bind:style="[styleColor, styleSize]"></div>
      data: {
       styleColor: {
          color: 'red' 
       }, 
      styleSize:{ 
         fontSize:'23px'
       }
     } 
    

76、直接给一个数组项赋值,Vue 能检测到变化吗?

以下情况,不能检测到以下数组的变动

  • 利用索引直接设置一个数组项时:vm.items[indexOfItem] = newValue
  • 直接修改数组的长度时:vm.items.length = newLength
  • 解决方法
    1. 用索引设置一个数组项
     // Vue.set 
    Vue.set(vm.items, indexOfItem, newValue)
     // vm.$set,Vue.set的一个别名 
    vm.$set(vm.items, indexOfItem, newValue)
     // Array.prototype.splice 
    vm.items.splice(indexOfItem, 1, newValue) 
    
    1. 改数组的长度
    // Array.prototype.splice 
    vm.items.splice(newLength) 
    

77、Vue 的父组件和子组件生命周期钩子函数执行顺序?

Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:

  • 加载渲染过程

    父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

  • 子组件更新过程

    父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

  • 父组件更新过程

    父 beforeUpdate -> 父 updated

  • 销毁过程

    父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

78、在哪个生命周期内调用异步请求?

可以在钩子函数 created、beforeMount、mounted 中进行调用

  • created 钩子函数中调用异步请求优点
    • 能更快获取到服务端数据,减少页面 loading 时间;
    • ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;

79、谈谈你对 keep-alive 的了解?

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染

特性:

  • 一般结合路由和动态组件一起使用,用于缓存组件
  • 提供 includeexclude 属性,两者都支持字符串或正则表达式
    • include 表示只有名称匹配的组件会被缓存
    • exclude 表示任何名称匹配的组件都不会被缓存
    • 其中 exclude 的优先级比 include 高;
  • 对应两个钩子函数 activateddeactivated
    • activated:当组件被激活时,触发钩子函数 activated,
    • deactivated:当组件被移除时,触发钩子函数 deactivated。

80、使用过 Vue SSR 吗?说说 SSR?

SSR服务端渲染:将标签渲染成的整个html片段的工作在服务端完成,服务端形成的html片段直接返回给客户端

  • 服务端渲染的优点:

    • 更好的 SEO: 因为 SPA 页面的内容是通过 Ajax 获取,而搜索引擎爬取工具并不会等待 Ajax 异步完成后再抓取页面内容,所以在 SPA 中是抓取不到页面通过 Ajax 获取到的内容;而 SSR是直接由服务端返回已经渲染好的页面(数据已经包含在页面中),所以搜索引擎爬取工具可以抓取渲染好的页面;
    • 更快的内容到达时间(首屏加载更快): SPA 会等待所有 Vue 编译后的 js 文件都下载完成后,才开始进行页面的渲染,文件下载等需要一定的时间等,所以首屏渲染需要一定的时间;SSR 直接由服务端渲染好页面直接返回显示,无需等待下载 js 文件及再去渲染等,所以 SSR 有更快的内容到达时间;
  • 服务端渲染的缺点:

    • 更多的开发条件限制: 例如服务端渲染只支持 beforCreate 和 created 两个钩子函数,这会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行;并且与可以部署在任何静态文件服务器上的完全静态单页面应用程序 SPA 不同,服务端渲染应用程序,需要处于 Node.js server 运行环境;
    • 更多的服务器负载:在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用CPU 资源 (CPU-intensive - CPU 密集),因此如果你预料在高流量环境 ( high traffic ) 下使用,请准备相应的服务器负载,并明智地采用缓存策略

81、Vue 框架怎么实现对象和数组的监听?

通过遍历数组和递归遍历对象,从而达到利用 Object.defineProperty() 也能对对象和数组(部分方法的操作)进行监听。

82、Proxy 与 Object.defineProperty 优劣对比

  • Proxy

    • 优点
      • Proxy 可以直接监听对象而非属性;
      • Proxy 可以直接监听数组的变化;
      • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等
      • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的
      • Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
    • 缺点
      • 存在浏览器兼容性问题,无法用 polyfill 磨平
      • 需要等到下个大版本( 3.0 )才能用 Proxy 重写。
  • Object.defineProperty

    • 优点
      • 兼容性好,支持 IE9
    • 缺点
      • 只能通过遍历对象属性直接修改
      • 拦截方法较少

82、介绍下vue单页面和多页面区别

  • 单页面

    首次加载缓慢,但是后面的加载优势就会超过多页面了
    不需要考虑太多的兼容性就使用vue来做单页面

  • 多页面

    首次加载快,但是后面每次都要进行加载。

83、Vue 使用 vm.$set() 解决对象新增属性不能响应的问题

由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的

  • vm.$set 的实现原理:

    • 数组:直接使用数组的 splice 方法触发相应式;
    • 对象
      1. 会先判读属性是否存在、对象是否是响应式
      2. 如要对属性进行响应式处理,则会调用 defineReactiv 方法进行响应式处理

        defineReactive 方法就是 Vue 在初始化对象时,给对象属性采用 Object.defineProperty 动态添加 getter 和 setter 的功能所调用的方法

84、Vue中key的作用 ,不加Key会怎么样

key 是为 Vue 中 vnode 的唯一标记,通过这个 key, diff算法的操作可以更准确、更快速。

  • 更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。
  • 更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快。
  • 不使用key:插入新元素时会导致所有列表DOM重新渲染,降低diff算法的性能,增加性能消耗,降低准确性

85、Vue的项目优化

  1. 代码层面的优化
    • v-if 和 v-show 区分使用场景
    • computed 和 watch 区分使用场景
    • v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
    • 长列表性能优化(节流懒加载)
    • 事件的销毁
    • 图片资源懒加载
    • 路由懒加载
    • 第三方插件的按需引入
    • 优化无限列表性能
    • 服务端渲染 SSR or 预渲染
  2. Webpack 层面的优化
    • Webpack 对图片进行压缩
    • 减少 ES6 转为 ES5 的冗余代码
    • 提取公共代码
    • 模板预编译
    • 提取组件的 CSS
    • 优化 SourceMap
    • 构建结果输出分析
    • Vue 项目的编译优化
  3. 基础的 Web 技术的优化
    • 开启 gzip 压缩
    • 浏览器缓存
    • CDN 的使用
    • 使用 Chrome Performance 查找性能瓶颈

86、vue如何优化页面加载

使用cdn,不要打包一些公共的文件和组件库

87、什么是路由懒加载

通过异步的方式来加载对应的路由组件,提高页面相应速度

88、vue中有哪些内置组件

component、 slot 、transtion 、fliters

89、ssr是什么

服务端渲染

90、vue中router-link和传统a链接的区别

  • router-link

    避免了不必要的重渲染,它只更新变化的部分从而减少DOM性能消耗

  • \<a>标签

    每次跳转都得重渲染一次,消耗了大量的DOM性能

91、vue插槽是什么

插槽就是子组件中的提供给父组件使用的一个占位符,用 表示
父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。

93、methods和computed的区别?

methods里面存放的方法每次调用都会重新计算(不会缓存)

computed里面的方法调用计算后,当其参数不发生改变时再次调用,直接返回上次计算的结果,不重新计算(会响应数据缓存)

94、Vue的传参方法

  • 属性传值、 r e f s 、 refs、 refsparent、通知传值(广播传值)、本地传值、路由传值
  • 父向子传值:v-bind属性绑定(props)
  • 子向父传值:v-on 事件绑定
  • 兄弟组件之间共享数据:EventBus( o n 数 据 接 收 方 , on数据接收方, onemit发送数据的那个组件)

95、vue-router路由守卫

路由跳转过程中自动执行的钩子函数

  • 全局守卫: 一般写在路由配置当中

    • router.beforeEach(function (to,form,next){})
    • router.afterEach(function (to,form){})
    • router.beforeResolve(function (to,form,next){})
  • 路由独享守卫: 写在路由配置当中

    • beforeEnter()
  • 组件内守卫: 写在组件内

    • beforeRouteEnter() 进入路由组件
    • beforeRouteLeave() 离开路由组件(一般是复用的路由)
    • beforeRouteUpdate() 路由更新组件

96、vuex刷新数据页面会丢失吗?怎么解决

会丢失,使用本地存储保存

97、虚拟DOM和DIFF算法?

Diff算法:将DOM抽象为虚拟DOM(是个对象), 然后通过新旧虚拟DOM 对比这两个对象的差异,最终只把变化的部分重新渲染,提高渲染效率的过程;

原理:通过JS层面的计算,返回一个patch对象,即补丁对象,在通过特定的操作解析patch对象,完成页面的重新渲染

98、scss是什么

预处理css,把css当前函数编写,可以定义变量,嵌套

99、active-class是哪个组件的属性

vue-router模块的router-link组件。

100、说出至少4种vue当中的指令和它的用法?

v-if:判断是否隐藏;
v-for:数据循环出来;
v-bind:class:绑定一个属性;
v-model:实现双向绑定

101、请说出vue.cli项目中src目录每个文件夹和文件的用法

assets文件夹是放静态资源;
components是放组件;
router是定义路由相关的配置;
view视图;
app.vue是一个应用主组件;
main.js是入口文件

102、prop 验证,和默认值

default:默认值
type:类型校验使用
required:是否必要

103、vue的数据代理

data中的所有属性的操作(读/写)由vm对象来代理操作

  • 好处: 通过实例对象就可以方便的操作data中的数据
  • 实现:
    1. 通过Object.defineProperty(vm, key, {})给vm添加与data对象的属性对应的属性
    2. 所有添加的属性都包含get/set方法
    3. 在get/set方法中去操作data中对应的属性

属性描述符

  • 数据描述符
    • configurable:是否可以重新定义
    • enumerable:是否可以枚举
    • value:初始值
    • writable:是否可以修改属性值
  • 访问描述符
    • get:是一个回调函数,根据其他相关的属性动态计算得到当前属性值
    • set:也是一个回调函数,监视当前属性值的变化,更新其他相关的属性值

104、对于即将要来的vue3.0你有什么了解

Vue 3.0 的目标是让 Vue 核心变得更小、更快、更强大

  1. 监测机制的改变

    带来基于代理 Proxy 的 observer 实现,提供全语言覆盖的反应性跟踪,

    消除了 Vue 2 当中基于 Object.defineProperty 的实现所存在的很多限制:

    • 只能监测属性,不能监测对象
    • 检测属性的添加和删除;
    • 检测数组索引和长度的变更;
    • 支持 Map、Set、WeakMap 和 WeakSet。

    新的 observer 还提供了以下特性:

    • 用于创建 observable 的公开 API。这为中小规模场景提供了简单轻量级的跨组件状态管理解决方案。
    • 默认采用惰性观察。在应用启动时减少带来明显的开销
    • 更精确的变更通知。
    • 更好的调试功能:我们可以使用新的 renderTracked 和 renderTriggered 钩子精确地跟踪组件在什么时候以及为什么重新渲染。
  2. 模板

    改了作用域插槽

    • 2.x 的机制导致作用域插槽变了,父组件会重新渲染
    • 3.0 把作用域插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能。
  3. 对象式的组件声明方式

    • vue2.x 中的组件是通过声明的方式传入一系列 option,和 TypeScript 的结合需要通过一些装饰器的方式来做,虽然能实现功能,但是比较麻烦。
    • 3.0 修改了组件的声明方式,改成了类式的写法,这样使得和 TypeScript 的结合变得很容易。
  4. 其它方面的更改

    • 支持自定义渲染器,从而使得 weex 可以通过自定义渲染器的方式来扩展,而不是直接 fork 源码来改的方式。
    • 支持 Fragment(多个根节点)和 Protal(在 dom 其他部分渲染组建内容)组件,针对一些特殊的场景做了处理。
    • 基于 treeshaking 优化,提供了更多的内置功能。

105、Vuex和redux有什么区别,他们的共同思想

Vuex弱化dispatch,通过commit进行store状态的一次变更
取消了action概念,不必传入特定的action形式进行指定变更
弱化reducer,基于commit参数直接对数据进行转变,使得框架更加简易

  • Vuex改进了Redux中的Action和Reducer函数,以mutations变化函数取代Reducer,无需switch,只需在对应的mutation函数里改变state值就可以
  • Vuex由于Vue自动重新渲染的特性,无需订阅重新渲染函数,只要生成新的state就可以
  • Vuex数据流的顺序是:View调用store.commit提交对应的请求到Store中对应的mutation函数 -> store改变(vue检测到数据变化自动渲染)

共同思想

  • 单一的数据源
  • 变化可以预测
  • 本质上:Redux和Vuex都是对MVVM思想的服务,将数据从视图中抽离的一种方案
  • 形式上:Vuex借鉴了Redux,将store作为全局的数据中心,进行数据管理
Logo

前往低代码交流专区

更多推荐