笔试/面试——Vue(全!)

目录

一、Vue的最大的优势是什么?

二、在使用计算属性的时候,函数名和data数据源中的数据可以同名吗?

三、Vue和jQuery两者之间的区别?

四、Vue2.0兼容IE哪个版本以上吗?

五、跟keep-alive有关的生命周期是哪些?

1、activated:

2、deactivated:

六、Vue中key的原理?说说对它的理解?

七、Object.defineProperty 和 Proxy 的区别

八、style加scoped属性的用途和原理

九、Vue组件如何进行传值?

1)父传子

1、属性传值:

2、this.$refs.ref

3、this.$children

2)子传父

1、自定义事件 =>  $emit

2、传值的sync

3、传值的v-model

4、this.$parent 或者 this.$root

3) 多层组件传值 $listeners/$attrs

4) 非父子组件之间传递数据

十、watch的属性用箭头函数定义结果会怎么样?

十一、组件的命名规范

十二、Vue自定义事件中 父组件怎么接受 子组件的多个参数?

十三、Vue给组件绑定事件无效 怎么解决?

十四、Vue变量名如果以 _  、$ 开头的属性会发生什么问题?怎么访问到它们的值?

十五、组件中写name选项有什么作用?

十六、使用Vue写一个tab切换

十七、Vue数据双向绑定的原理是什么?

十八、在Vue中使用this应该注意哪些问题?

十九、prop 验证的 type 类型有哪几种?

二十、对Vue组件的设计原则的理解  / 封装Vue组件的过程?

二十一、Vue组件里的定时器要怎么销毁?

1、页面上只有单个定时器:

2、页面上有很多定时器:

二十二、AJAX、Fetch、axios这三者有什么区别?

二十三、Vue中如何使用event对象?

二十四、对单向数据流 和 双向数据流的理解?

1)单向数据流:

2)双向数据流:

3、响应式数据设计原理:

 二十五、对v-clock和v-pre指令的理解?

二十六、常用的修饰符有哪些?

1)事件修饰符

2) 按键修饰符

3) 系统修饰键 

4) 鼠标按键修饰符 

5) 表单修饰符

二十七、怎么捕获 Vue 组件的错误信息?

二十八、Vue 生命周期总共分为几个阶段?

1、beforeCreate 

2、created

3、beforeMount

4、mounted

5、beforeUpdate

6、updated

7、activated

8、deactivated

9、beforeDestroy

10、destroyed

11、errorCaptured(2.5.0+ 新增)

二十九、watch 怎么深度监听对象变化?

三十、vue 怎么获取 DOM 节点?

三十一、vue-loader 是什么?它有什么作用?

三十二、v-el的作用是什么?

三十三、对 SPA 单页面的理解,它的优缺点分别是什么?

三十四、Vue 常用的指令有哪些?

1.v-text

2.v-html

3.v-show

4.v-if

5.v-else

6.v-else-if

7.v-for

8.v-on

9.v-bind

10.v-model

11、v-cloak 

12、v-pre 

13、v-slot :插槽

14、v-once :

三十五、使用 Vue 的时候一下加载造成页面卡顿,该如何解决?

三十六、第一次加载页面时会触发哪几个钩子?

三十七、你对 Vue.js 的 template 编译的理解?

三十八、axios 是什么?怎样使用它?怎么解决跨域的问题?

三十九、组件和插件有什么区别?

四十、对选项 el,template,render 的理解?

四十一、v-if 和 v-for 的优先级是什么?如同时出现,应怎么优化性能更好

四十二、Vue 组件 data 为什么必须为函数呢?

四十三、Vue-cli 用自定义的组件?有遇到过哪些问题吗?

四十四、怎么在 watch 监听开始之后立即被调用?

四十五、watch 和计算属性有什么区别?


一、Vue的最大的优势是什么?

Vue是一款简单易学、双向数据绑定、组件化的框架

1、Vue.js可以进行组件化开发,使代码编写量大大的减少,读者更加容易理解

2、Vue.js最突出的优势在于可以对数据进行双向绑定

3、使用Vue.js编写出来的页面的效果本身就是响应式的,这使网页在各个设备都能显示出非常好的效果

4、相比传统的页面同超链接实现页面的切换和跳转,Vue使用路由不会刷新页面

5、Vue是单页面应用,使页面局部刷新,不用每次跳转页面都请求所有数据和DOM,这样大大加快了访问速度和提升用户体验

6、它的第三方UI组件库使用起来节省很多开发时间,从而提升开发效率

二、在使用计算属性的时候,函数名和data数据源中的数据可以同名吗?

本来不应该同名,同名了就说明命名不规范。若eslint配置比较严格的话,同名是编译不通过的。

如果同名,那么就会有覆盖的现象==>

初始化的顺序是: computed  methods  data  props    (C M D P)

本质上这些都是要挂载到this上面的,如果重名,后面出现的属性自然就会覆盖之前挂载的属性

三、Vue和jQuery两者之间的区别?

1、jQuery:

jQuery是曾经很流行的web前端js库,现在国内外使用都使用其它的js库代替它了,随着浏览器厂商对HTML5规范统一遵循以及ECMA6在浏览器端的实现,它的使用率会越来越低。

2、Vue:

Vue是一个兴起的前端js库,是一个精简的MVVM。

从技术角度讲,Vue.js专注于MVVM模型的ViewModel层,它通过双向数据绑定把View和Model层连接起来,通过对数据的操作就可以完成对页面视图的渲染。

当然还有其它的MVVM框架:Angular、react等。但是Vue更简单、快速、组合

3、Vue和jQuery的区别:

1) jQuery是使用选择器选取DOM对象,对其进行赋值、取值、事件绑定等操作

其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和页面是在一起的。

2) Vue是通过Vue对象将数据和View完全分离开

对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定==>这就是MVVM

四、Vue2.0兼容IE哪个版本以上吗?

不支持IE8及以下,部分兼容IE9,完全兼容IE10以上。

因为Vue的响应式原理是基于ES5的Object.defineProperty,这个方法不支持IE8及以下。

五、跟keep-alive有关的生命周期是哪些?

1、activated:

页面第一次进入的时候,钩子触发的顺序就是created、mounted、activated

2、deactivated:

页面退出的时候会触发deactivated,当再次前进或者后退的时候,只触发activated

六、Vue中key的原理?说说对它的理解?

1、如果没有唯一的key,数据更新的时,相同节点更点前后无法准确的一 一对应起来,会导致更新的效率降低。

2、作用:为了高效的更新虚拟DOM

3、当页面的数据发生变化的时,Diff算法只会比较同一层级的节点

1) 如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点

2) 如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新

七、Object.defineProperty 和 Proxy 的区别

1、Proxy可以直接监听对象,而非属性

2、Proxy可以直接监听数组的变化

3、Proxy有多达13种拦截方式,不限于apply、ownKeys、deletdProperty、has等是Object.defineProperty不具备的

4、Proxy返回的是一个新的对象,我们可以只操作新的对象达到目的

Object.defineProperty只能遍历对象属性直接修改

5、Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利

6、Proxy(Vue3.0)存在浏览器兼容性问题,Object.defineProperty(Vue2.0)兼容性好,支持IE9

八、style加scoped属性的用途和原理

用途:防止全局同名CSS污染

原理:在标签加上v-data-something属性,再在选择器时加上对应[v-data-something],即CSS带属性选择器,以此完成类似作用域的选择方式

九、Vue组件如何进行传值?

1)父传子

1、属性传值:

父组件内设置要传的数据,在父组件中引用的子组件上 绑定一个自定义属性并把数据绑定在自定义属性上,在子组件中添加参数props接受即可

2、this.$refs.ref

在子组件中加上 ref,然后通过 this.$refs.ref 属性值 访问子组件

3、this.$children

在父组件内部通过 this.$children[索引号] 访问子组件

2)子传父

1、自定义事件 =>  $emit

子组件通过vue实例方法$emit 进行 触发 父组件的自定义事件 并且 可以携带参数

2、传值的sync

跟$emit相同,只是这个方法省略了写事件名字

3、传值的v-model

4、this.$parent 或者 this.$root

子组件通过 this.$parent 或者 this.$root 访问到父组件或者根组件

3) 多层组件传值 $listeners/$attrs

多层组件向下传值$attrs,首先在第一层子组件上使用 '属性="数据" ' 将值传
给子组件,再到子组件模板内部使用 v-bind="属性",注意该“属性”不能被定义为子组
件的 props 属性
多层组件向下传值$listeners,在父组件内部定义好 methods 方法,在第一层
组件的模板内部使用 '@事件名="methods 方法"',再到子组件模板内部使用 v-on="事件
名",在需要传值的组件内部使用 this.$emit("事件名",val1,val2,val3……)

4) 非父子组件之间传递数据

第一步:引入第三方 new vue 定义为 eventBus
第二步:在组件中 created 中订阅方法 eventBus.$on("自定义事件名",methods 中
的方法名)
第三步:在另一个兄弟组件中的 methods 中写函数,在函数中发布 eventBus 订阅的
方法 eventBus.$emit("自定义事件名”)
第四步:在组件的 template 中绑定事件(比如 click)

十、watch的属性用箭头函数定义结果会怎么样?

this是undefine,要更改的属性也会报错

==>TypeError 错误  :Cannot read property  'xxx' of undefined

因为箭头函数绑定父级作用域的上下文,所以就不会绑定vue实例

十一、组件的命名规范

给组件命名有两种方式:

1、链式命名 my-component

2、大驼峰命名 MyComponent

字符串模板中:
<my-component></my-component> 和 <MyComponent></MyComponent> 都 可 以 使 用
在 非 字 符 串 模 板 中
最 好 使 用 <MyComponent></MyComponent>,
因为要遵循 W3C 规范中的自定义组件名 (字母全小写且 必须包含一个连字符),避免和当前以及未来的 HTML 元素相冲突。
Tips:

1. 在html中不允许使用驼峰!
html中的组件必须用短横线命名,例如my-component
在组件中, 父组件给子组件传递数据必须用短横线,例如my-msg

2. 在template中必须使用驼峰

3.在组件的data中this.XXX引用时,只能是驼峰命名方式,比如this.myMsg

4.文件名最好全小写,因为有些古老的操作系统(window10)可能不能识别大小写,防止2个大小写文件重名。
5.组件首字母最好大写

十二、Vue自定义事件中 父组件怎么接受 子组件的多个参数?

this.$emit("eventName",data)  //data为一个对象

十三、Vue给组件绑定事件无效 怎么解决?

两种方式:

1、组件外部加修饰符     .navtive

2、组件内部声明$emit("自定义事件")

十四、Vue变量名如果以 _  、$ 开头的属性会发生什么问题?怎么访问到它们的值?

实例创建后,可以通过vm.$data访问原始数据对象。Vue实例也代理了data对象上所有的属性,因此访问vm.a等价于访问vm.$data.a

以_或$开头的属性不会被Vue实例代理,因为它们可能和Vue内置的属性、API方法冲突。可以使用例如vm.$data._property的方法访问这些属性

十五、组件中写name选项有什么作用?

1、项目使用keep-alive的时候,可搭配组件name进行缓存过滤

2、DOM做递归组件时,需要调用自身的name

3、Vue-devtools调试工具里 显示的组件名称 是由vue中组件name决定的

十六、使用Vue写一个tab切换

1、v-for循环,利用下标和v-show/v-if控制显示

2、动态组件component,控制其属性is的值

3、引入vueRouter,定义路由规则,通过router-link/router-view实现

十七、Vue数据双向绑定的原理是什么?

Object.defineProperty定义新属性或修改原有的属性

原理:

用Object.defineProperty这个方法,里面定义了setter和getter方法,通过观察者模式(发布订阅模式)来监听数据的变化,从而做相应的逻辑处理

vue2.0:vue实现数据双向绑定主要是:

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

当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

  vue3.0 --使用es6 proxy 代理了data对象
 

十八、在Vue中使用this应该注意哪些问题?

1、Vue中使用匿名函数,会出现this指针改变

解决方法:

1)使用箭头函数

2)定义变量绑定this至vue对象

2、Vue的data避免使用箭头函数

3、Vue中的methods中函数尽量不要使用箭头函数,会改变this指向,在Vue-cli构建的项目中this会为undfined

4、生命周期的钩子函数不能使用箭头函数,否则this不能指向vue实例

十九、prop 验证的 type 类型有哪几种?

props:{ 
title:String, 
likes: Number, 
isPublished: Boolean, 
commentIds: Array,
 author: Object,
 callback: Function, 
contactsPromise: Promise 
}

二十、对Vue组件的设计原则的理解  / 封装Vue组件的过程?

对Vue组件的理解:
组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块
解决了我们传统项目开发:效率低、难维护、复用性等问题。

  封装Vue组件的过程:

        1)使用 Vue.extend() 方法创建一个组件

        2)然后使用 Vue.component ()方法注册组件

        3)如果 子组件需要数据,可以在 props 中接受定义

        4)最后,子组件修改好数据后,想把数据传递给父组件, 可以采用$emit() 方法

1.容错处理, 这个要做好, 极端场景要考虑到
2.缺省值(默认值)要有, 一般把应用较多的设为缺省值
3.颗粒化, 把组件拆分出来.
4.一切皆可配置, 如有必要, 组件里面使用中文标点符号, 还是英文的标点符号, 都
要考虑到
5.场景化, 如一个 dialog 弹出, 还需要根据不同的状态封装成 success, waring, 等
6.有详细的文档/注释和变更历史, 能查到来龙去脉
7.组件名称, 参数 prop, emit, 名称设计要通俗易懂, 最好能做到代码即注释这种程
8.可拓展性, 前期可能不需要这个功能, 但是后期可能会用上, 要预留什么, 要注意
什么, 心里要有数
9.规范化
10.分阶段: 不是什么都要一期开发完成看具体业务

二十一、Vue组件里的定时器要怎么销毁?

1、页面上只有单个定时器:

const timer = setInterval(() => { }, 1000)
this.$once("hook:beforeDestroy", () => { clearInterval(timer) })

2、页面上有很多定时器:

在data选项中创建一个对象timer,给每个定时器取个名字一 一 映射在对象timer中,在beforeDestroy构造函数中:

for(let k in this.timer) {clearInterval(k)}

二十二、AJAX、Fetch、axios这三者有什么区别?

1、AJAX
是最早出现发送后端请求的技术
属于原生 js 范畴
核心是使用 XMLHttpRequest 对象
使用较多并有先后顺序的话,容易产生回调地狱
2、Fetch
号称可以代替 AJAX的技术,它并不是对 AJAX进一步封装
它属于原生 js 范畴。
没有使用XMLHttpRequest 对象
是基于 es6 中的 Promise 对象设计的,参数和 jQuery 中的 ajax 类似,
3、axios
不是原生 js,
使用时需要对其进行安装,客户端和服务器端都可以使用,
基于 promise 对象,可以在请求和相应阶段进行拦截

二十三、Vue中如何使用event对象?

1、@click=“func” 默认第一个参数传入 event 对象
2、@click="func(0, $event)"
如果自己需要传入参数和 event 对象,则需要使用$event 来获取 event 对象并传入 func

二十四、对单向数据流 和 双向数据流的理解?

1)单向数据流:

所有状态的改变可记录、可跟踪,源头易追溯;
所有数据只有一份,组 件数据只有唯一的入口和出口,
使得程序更直观更容易理解,有利于应用的可维护性;
一 旦数据变化,就去更新页面(data-页面),但是没有(页面-data);
如果用户在页面上做了变动,那么就手动收集起来(双向是自动),合并到原有的数据中。
1、数据从父级组件传递给子组件,只能单向绑定。
2、子组件内部不能直接修改从父级传递过来的数据。
3、所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行,这样会防止从子组件意外改变父级组
件的状态, 从而导致你的应用的数据流向难以理解。
4、每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值,这
意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制
台中发出警告。
5、子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,
由父组件修改。

2)双向数据流:

(双向数据绑定的概念要包括响应式数据绑定,所以要先说响应式数据绑定概念)


代码改变UI,UI也能改变代码

如果数据容器中的数据变了也会让页面刷新(DOM操作让页面改变)

如果用户操作DOM,改变了页面,反之也会让数据容器中的数据值改变

无论数据改变,或是用户操作,都能带来互相的变动,自动更新。

2、双向数据绑定的实现: 2种方式
1.自己实现=>利用input事件,用户交互的时候,获取用户输入的值,然后把值绑定到data容器中

2.系统指令:v-model

3、响应式数据设计原理:

vue2.0:

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

当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。

用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue3.0

使用es6 proxy 代理了data对象
 

总结:

1.单向数据流,只允许父组件传递值给子组件,不能反向传递值。
2.双向数据绑定,在单向数据流的基础上 通过 自定义事件 改变父组件中的数据值。
3.响应式原理,通过数据劫持(Object.defineProperty) 和 发布订阅者模式实现。

 二十五、对v-clock和v-pre指令的理解?

v-clock:
只是在标签中加入一个 v-cloak 自定义属性
在 HTML 还编译完成之后该 属性会被删除
用以去掉界面双大括号的闪现问题
v-pre
静默-跳过编译   ==>   可以用来阻止预编译
有 v-pre 指令的标签内部的内容不会被编译,会原样输出。

二十六、常用的修饰符有哪些?

1)事件修饰符

1. .stop - 阻止单击事件继续传播, 也就是阻止冒泡
2. .prevent - 提交事件不再重新加载页面, 可以用来阻止表单提交的默认行为
注意点: .stop和.prevent可以串联在一起使用,都会生效

3. .capture - 内部元素触发的事件先在此处理,然后才交由内部元素进行处理
4. .self - 只当在 event.target 是当前元素自身时触发处理函数,即事件不是从内部元素触发的
注意点: 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。

因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

5. .once - 点击事件将只会触发一次, 不只能对原生DOM时间生效,还可以用在自定义组件上
6. .passive - 立即触发默认行为,能够提升移动端性能,和.prevent一起使用时.prevent会被忽略并警告
7. .native - 使用时将被当做原生的HTML标签看待,绑定事件可以生效

2) 按键修饰符

1. .keyup - 键盘抬起
2. .keydow - 键盘按下
3. 按键码 - 在按键修饰符后面添加,用于监听键盘按下哪个键
常用按键码: enter    tab  delete (捕获“删除”和“退格”键)   esc   space   up   down  left   right

3) 系统修饰键 

ctrl    alt    shift   meta
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
注意点: 修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。

.exact 修饰符 - 使用系统修饰符时使用可以单击系统修饰键触发,不适用系统修饰符时使用

4) 鼠标按键修饰符 

.left - 只有鼠标左键点击触发
.right - 只有鼠标右键点击触发
.middle - 只有鼠标中键点击触发

5) 表单修饰符

1. .lazy - 在表单输入时不会马上显示在页面,而是等输入完成失去焦点时才会显示在页面
2.  .trim - 过滤表单输入时前后的空格
3. .number - 限制输入数字或将输入的数据转为数字

二十七、怎么捕获 Vue 组件的错误信息?

1、errorCaptured
errorCaptured 是组件内部钩子,
当捕获一个来自子孙组件的错误时被调用,
接收 error、vm、info 三个参数,return false 后可以阻止错误继续向上抛出。
2、errorHandler
errorHandler 为全局钩子,
使用 Vue.config.errorHandler 配置,
接收参数与 errorCaptured 一致,
后可捕捉 v-on 与 promise 链的错误,
可用于统一错误处理与错 误兜底。

二十八、Vue 生命周期总共分为几个阶段?

完整生命周期(vue、react)

笔试题/面试题——事件以及使用、生命周期(Vue2.0 (11个)、 Vue3.0 (选项式API [14个] 、组合式API [13个])、React (9个))_爱喝牛奶~的博客-CSDN博客

Vue 实例从创建到销毁的过程,就是生命周期。
也就是从开始创建、初始化数据、编译模板、挂载 Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

1、beforeCreate 

组件实例刚被创建,组件属性计算之前。

在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用

2、created

组件实例刚被创建,属性已绑定,但DOM还未生成。

在实例创建完成后被立即调用。
在这一步,实例已完成以下的配置:
数据观测 (data observer)属性和方法的运算,watch/event 事件回调。
然而,挂载阶段还没开始,$el 属性目前不可见。
建议数据请求放在这一阶段进行,到了之后的阶段再请求就一定会触发界面的二次渲染

3、beforeMount

模板编译/挂载之前。

在挂载开始之前被调用:相关的 render 函数首次被调用

4、mounted

模板编译/挂载之后。

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子,如果 root 实例挂
载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内

5、beforeUpdate

组件更新之前。

数据更新时调用,发生在虚拟 DOM 打补丁之前。
这里适合在更新之前访问现有的 DOM,
比如手动移除已添加的事件监听器,该钩子在服务器端渲染期间不被调用,
因为只有初次 渲染会在服务端进行

6、updated

组件更新之后

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子

7、activated

组件激活时调用。

keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用

8、deactivated

组件停用时调用。

keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用

9、beforeDestroy

组件销毁前调用。

实例销毁之前调用。
在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用

10、destroyed

组件销毁后调用。

Vue 实例销毁后调用。
调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监 听器会被移除,所有的子实例也会被销毁。
该钩子在服务器端渲染期间不被调用

11、errorCaptured(2.5.0+ 新增)

当捕获一个来自子孙组件的错误时被调用。

此钩子会收到三个参数:
错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串,
此钩子可以返回 false 以阻止该 错误继续向上传播

1、页面首次加载过程,会一次触发哪些钩子?

beforeCreate,created,beforeMount,mounted

2、beforeUpdate 、updated这两个钩子中,不能网络请求新数据,去更新数据源

因为会导致死循环

3、this.$el是什么?它在哪些钩子中才能访问?

它代表了当前组件的真实DOM,要在mounted之后才有

this.$el是指的关联的那个div

4、你用brforeCreate做过什么业务?

这个钩子中可以做网络请求,但是vm没有构建完毕,此时数据方法等等的劫持还没有完成,不能操作this,因此可以做预加载

5、网络请求应该在什么钩子中,为什么?

可以放在data生成以后更新数据之前 的所有钩子中
具体的更具业务需求来  常见的放在created或者mounted中

6、你用销毁钩子做过什么?

常常去把一些运行着的代码停下来
本地或者网络请求来记录用户的配置信息或者偏好设置

二十九、watch 怎么深度监听对象变化?

1、有个原则监听谁,写谁的名字,然后是对应的执行函数,
第一个参数为最新的改变值,第二个值为上一次改变的值;
注意: 除了监听 data,也可以监听计算属性 或者一个函数的计算结果
2、启用深度监听对象

 - 监视reactive定义的响应式数据时,oldvalue无法正确获取,强制开始了深度监视(deep的配置失效)
  - 监视reactive定义的响应式数据的某一个值时:deep配置有效

   watch:{
            a:{
                handler:function(newvalue,oldvalue),
                deep:true
            }
        }

三十、vue 怎么获取 DOM 节点?

通过在标签内写: ref=“myinput”

获取: let input=this.$refs.myinput

三十一、vue-loader 是什么?它有什么作用?

Vue Loader 是一个 webpack 的 loader,它允许你以一种名为单文件组件 (SFCs)的
格式撰写 Vue 组件

它可以解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理

Vue Loader 还提供了很多酷炫的特性:
1.允许为 Vue 组件的每个部分使用其它的 webpack loader,例如在 <style> 的部分
使用 Sass 和在 <template> 的部分使用 Pug;
2.允许在一个 .vue 文件中使用自定义块,并对其运用自定义的 loader 链;
3.使用 webpack loader 将 <style> 和 <template> 中引用的资源当作模块依赖来
处理;
4.为每个组件模拟出 scoped CSS;
5.在开发过程中使用热重载来保持状态。
简而言之,webpack 和 Vue Loader 的结合为你提供了一个现代、灵活且极其强大的
前端工作流,来帮助撰写 Vue.js 应用。

三十二、v-el的作用是什么?

可以获取到DOM对象

提供一个 在页面上 已存在的  DOM 元素 作为  Vue 实例的挂载目标.
可以是 CSS 选择 器,也可以是一个 HTMLElement 实例。

三十三、对 SPA 单页面的理解,它的优缺点分别是什么?

SPA 应用就是一个 web 应用,
可理解为:是一种只需要将单个页面加载到服务器之中 的 web 应用程序。
当浏览器向服务器发出第一个请求时,服务器会返回一个 index.html 文件,
它所需的 js,css 等会在显示时统一加载,部分页面需要时加载。
优点:
1.良好的交互式体验。
意思是:用户无需刷新页面,获取数据通过异步 ajax 获取,页 面显示流畅
2.良好的前后端分离模式(MVVM),减轻服务端压力。
服务器只需要输出数据就可以, 不用管逻辑和页面展示,吞吐能力会提高几倍
3.共用同一套后端程序代码,不用修改就可用于 web 界面,手机和平板等客户端设备
缺点:
1.不利于 SEO 优化
2.由于单页应用在一个页面中显示,
所以不可以使用浏览器自带的前进后退功能,想要实现页面切换需要自己进行管理
3.首屏加载过慢(初次加载耗时多),
原因是:为了实现单页 web 应用功能及展示效果,
在页面初始化的时候就会将 js,css 等统一加载,部分页面在需要时加载。
当然也有解决方法。
解决方法:
①使用路由懒加载
②开启 Gzip 压缩
③使用 webpack 的 externals 属性把不 需要的库文件分离出去,减少打包后文件的大小
④使用 vue 的服务端渲染(SSR)

三十四、Vue 常用的指令有哪些?

1.v-text

更新元素的 content text,如果要更新部分的 content text,需要使用{ { content
text }}插值
<div v-text="msg"></div>
<div>{ {msg}}</div>

2.v-html

更新元素 innerHTML
<div v-html="html"></div>

3.v-show

根据表达式值的真假,切换元素的 display 属性
不论怎么样都会挂载,只是display为none  (高切换)
<div v-show="true">show time</div>

4.v-if

根据表达式值的真假条件渲染元素
v-if  的底层是销毁,不挂载  (高渲染)
<div v-if="true">hello</div>
v-for和v-if不要放在一起了,2.0 for优先,3.0 if优先, 但是都不太好

5.v-else

前一兄弟必须有 v-if 或 v-else-if
<div v-if="Math.random()" > 0.5">hello</div>
<div v-else>hello vue</div>

6.v-else-if

前一兄弟必须有 v-if 或者 v-else
<div v-if="Math.random() > 0.5">hello<div>
<div v-else-if="Math.random() < 0.5">hello world</div>
<div v-else>hello vue.js</div>

7.v-for

循环渲染元素
<div v-for="for item in items">
{ { item }}
<div>
<div v-for="for (item, index) in items">
{ { index }} : { { item }}
</div>

:key="index" / "id" 

 key可以绑数组的下标,但是不太好,原因==>数组下标和数组中的数据会错位

8.v-on

绑定事件监听

v-on:事件名(可以是自定义事件)=“监听器”

语法糖:@事件名.事件修饰符

事件修饰符:stop capture self  once  (可以连调)

<div v-on:click="clickme">click</div>
<div @on:click="clickme">click</div>
<div v-on:[event]>click<div>// 动态事件
<div @click.stop="click">click</div>// 停止事件冒泡
<div @click.prevent="dosome">click</div>// 阻止默认行为

9.v-bind

动态绑定一个或者多个属性,或一个组件的 prop 到表达式
语法糖: :属性名
<div v-bind:background="bg"></div>
<img :src="images" />
<div :class="{bg: isred}"></div>

10.v-model

在表单控件或着组件上创建双向绑定
<input v-model="message" placeholder="input me" />
<div>{ { message }}</div>

v-model=“msg”  组件也可以使用,组件内部要触发input书简,属性接受的属性名是value

v-model.trim="msg"     v-model.number="msg"    v-model.lazy="msg"

他也是一个语法糖  默认是   :value和 @input 的语法糖

11、v-cloak 

解决首屏闪烁bug,但是面试常问首屏问题并不是

12、v-pre 

静默,跳过编译, 如果有{ {}}等就会跳过,不会去编译

13、v-slot :插槽

 不同的版本用法不一样,组件内部用slot标签代表槽位,name属性是具名槽位,使用组件时,具名必须用template来插入数据  v-slot :槽位名

语法糖    #槽位名

14、v-once :

后面没有表达式

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点被视为静态内容并跳过,这可以用于优化更新性能

三十五、使用 Vue 的时候一下加载造成页面卡顿,该如何解决?

1、把不常改变的库放到 index.html 中,通过 cdn 引入
2、vue 路由的懒加载
3、不生成 map 文件
4、vue 组件尽量不要全局引入
5、使用更轻量级的工具库
6、开启 gzip 压缩
7、首页单独做服务端渲染

三十六、第一次加载页面时会触发哪几个钩子?

beforeCreate, created, beforeMount, mounted

三十七、你对 Vue.js 的 template 编译的理解?

简而言之:
就是先转化成 AST 树(虚拟语法树
再得到的 render 函数返回 Vnode(Vue 的虚拟 DOM 节点)
1、
首先通过 compile 编译器把 template 编译成 AST 语法树
(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式)
compile 是 createCompiler 的返回值,
createCompiler 是用以创建编译器的,另外 compile 还负责合并 option;
2、然后 AST 会经过 generate(将 AST 语法树转化成 render funtion 字符串的过
程)得到 render 函数,
render 的返回值是 Vnode,Vnode 是 Vue 的虚拟 DOM 节点,
里面有(标签名、子节点、文本等等)

三十八、axios 是什么?怎样使用它?怎么解决跨域的问题?

axios 的是一种异步请求,用法和 ajax 类似
安装 npm install axios --save 即可 使用
因为 axios 在 vue 中利用中间件 http-proxy-middleware 做了一个本地的代理服务 A,
相当于你的浏览器通过本地的代理服务 A 请求了服务端 B,浏览器通过服务 A 并没有跨 域,
因此就绕过了浏览器的同源策略,解决了跨域的问题。

三十九、组件和插件有什么区别?

组件 (Component) 是用来 构成App 的业务模块,它的目标是 App.vue。
插件 (Plugin) 是用来 增强技术栈的功能模块,它的目标是 Vue 本身。

四十、对选项 el,template,render 的理解?

el: 把当前实例挂载在元素上
template: 实例模版, 可以是.vue 中的 template, 也可以是 template 选项,
最终会编译成 render 函数
render: 不需要通过编译的可执行函数

四十一、v-if 和 v-for 的优先级是什么?如同时出现,应怎么优化性能更好

v-for 的优先级与 v-if 的优先级始终有一个更高,容易触发 v-if 为 false 但 v-for 并不重新运算的问题。

没有先后顺序的要求,但是先执行for

渲染过程为:对arr每一项先做map循环判断v-if给出的条件,再做一遍for 循环渲染

这样引起的问题是:arr 数组新增一项数据时,会对每一项再做一遍v-if 循环,然后for 循环渲染

vue2.0中v-if v-for写到一个元素中,v-for优先级更高

vue3.0不能写在一起,不然会报错

避免出现这种情况

如果实在需要,则在外嵌套 template,在这一层进行 v-if 判断,

然后在内部进行 v-for 循环,避免每次只有 v-if 只渲染很少一部分元素,也需要遍历同
级的所有元素

四十二、Vue 组件 data 为什么必须为函数呢?

对象为引用类型,
当重用组件时,由于数据对象都指向同一个 data 对象,
当在一个组件中修改 data 时,其他重用的组件中的 data 会同时被修改;
而使用返回对象的函数,由于每次返回的都是一个新对象(Object 的实例),引用地址不同,则不会出现这个问题。

四十三、Vue-cli 用自定义的组件?有遇到过哪些问题吗?

1、在 components 目录新建你的组件文件(indexPage.vue),script 一定要 export
default {}
2、在需要用的页面(组件)中导入:import indexPage from '@/components/
indexPage.vue'
3、注入到 vue 的子组件的 components 属性上面,components:{indexPage}
4、在 template 视图 view 中使用,例如有 indexPage 命名,使用的时候则
index-page。

四十四、怎么在 watch 监听开始之后立即被调用?

 immediate: true, deep : true     就可以监听到对象的变化
        let vm = new Vue({
            el: "#first",
            data: { msg: { name: '北京' } },
            watch: {
                msg: {
                    handler(newMsg, oldMsg) {
                        console.log(newMsg);
                    },
                    immediate: true,
                    deep: true
                }
            }
        })

四十五、watch 和计算属性有什么区别?

1.watch是侦听属性,computed是计算属性
2.computed是为了应对复杂的逻辑计算,watch是对数据的变化作出反应
3.computed是只有当缓存改变时才执行,watch是只要重新渲染就会执行
4.computed有缓存,watch没有缓存

四十六、vue 如何监听键盘事件?

1、 @keyup. 方法

<input @keyup.enter="function">

2、组合写法:

 3、vue 添加监听事件addEventListener

addEventListener第二个参数要绑在this上,即需要在methods中声明,否则销毁的时候会报错,在mounted中监听,在beforeDestroy中销毁

第一个参数表示事件名称(不含 on,如 "click")

第二个参数表示要接收事件处理的函数;

第三个参数为 useCapture)

mounted() {
    // 监听
    window.addEventListener('click', this.handleEventListener)
  },
beforeDestroy() {
  // 销毁
  window.removeEventListener('click', this.handleEventListener)
},
methods: {
  // 监听执行的事件
  handleEventListener() {
  },
}

四十七、对 keep-alive 的理解是什么?

1、 keep-alive--抽象组件--缓存
keep-alive 是 Vue 提供的一个抽象组件,用来对组件进行缓存,从而节省性能
由于 是一个抽象组件,所以在页面渲染完毕后不会被渲染成一个 DOM 元素。

希望在A组件时用户做了一些操作,切换B组件时做了一些操作,当切回A组件时希望记住A的操作,不要重新创建A组件,keep-alive可以缓存动态切换的组件

2、匹配首先检查组件自身的 name 选项,匿名组件不能被匹配。

3、 提供有 include  、exclude 、max

:include="/a|b/"  ==> 表示a,b组件被缓存,其他组件不缓存

exclude ==>代表除了xx组件其他的组件缓存

:max="2" ==> 代表缓存最近被渲染的2个组件。最多可以缓存多少个组件实例,一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉

4、提供了钩子函数==>

1、activated ==>在切回来的时候,又再次执行这个函数,就可以在里面做网络请求

2、deactivated==>离开某个组件的时候触发

四十八、怎么使 css 样式只在当前组件中生效?

在 style 上面写 scoped   ==>   <style scoped> </style>

四十九、对指令的理解?

第一: vue的指令本质是Vue为HTML标签新增的一些属性

vue所加的属性不仅仅包括HTML的`原本属性还有许多Vue自带的属性

第二: vue的指令有三种

(1)用于渲染数据的有 v-for v-show v-text v-html v-bind 等等

(2)用来交互的有 v-on v-model 等等

(3)就是自定义的vue属性 ==> directives

第三: 优点

自带的指令简单

可以通过自定义属性来满足项目对vue指令的需求


		<div id="app">
			<h2 v-color="'gold'">123</h2>
			<input type="text" v-focus>
		</div>
		<script>
			var vm = new Vue({
				el: "#app",
				data: {
				},
				methods: {
				},
				directives: {
					color: {
						inserted(el, option) {  //option是一个对象
							el.style.color = option.value
						}
					},
					focus:{
						inserted(el){
							el.focus()
						}
					}
				}
			})
		</script>

五十、Vue 中 solt 的使用方式,以及 solt 作用域插槽的用法?

1、使用方式
当组件当做标签进行使用的时候,用 slot 可以用来接受组件标签包裹的内容,
当给 solt 标签添加 name 属性的 时候,可以调换响应的位置。
2、插槽作用域
作用域插槽其实就是带数据的插槽,父组件接收来自子组件的 slot 标签上通过
v-bind 绑定进而传递过来的数 据,父组件通过 scope 来进行接受子组件传递过来的
数据。

具名插槽 slot,slot-scope过时了 2.6.0使用v-slot
语法:v-slot:插槽名   语法糖:#插槽名
没有指定插槽名就是默认插入到插槽,不给插槽插入数据的话,就会使用组件的slot中的数据
插槽名不用使用引号引起来,直接写变量名
插入的内容必须是template标签或者组件 不能是原生的元素

一般用在UI项目框架中

 插槽的传值技术==>数据共享,共用

  设计组件里面:(Box.vue)

    默认槽位:< slot> < /slot>

    具名槽位:< slot name="s1"> < /slot>  < slot name="s2"> < /slot>

  使用组件时: (APP.vue)

     < 组件名> 尖括号中的东西插入默认槽位 < /组件名>

     < 组件名>

             < template v-slot:s2>插入东西必须放这个标签中,老版本不用< template>

             < template #s1>插入东西必须放这个标签中,老版本不用< template>

    < /组件名>

五十一、Vue 的脚手架是什么?有什么作用?

vue 脚手架指的是 vue-cli,
它是一个专门 为 单页面应用 快速搭建繁杂的脚手架
它可以轻松的 创建 新的应用程序
而且可用于 自动生成 vue 和 webpack 的项目模板。

五十二、说一下你在 Vue 中踩过的坑

1、第一个是给对象添加属性的时候,直接通过给 data 里面的对象添加属性然后赋值,
新添加的属性不是响应式的
解决办法:通过 Vue.set(对象,属性,值)这种方式就可以达到,对象新添加的属性是响应式的

2、数组的下标不能劫持

解决方法:

2.1、this.$set

2.2、Vue.set

2.3、刷新页面中的无关紧要的变量,比如:this.msg="原本的内容" ,程序员常用,但是不是官方的解决方法)

3、在 created 操作 dom 的时候,是报错的,获取不到 dom,这个时候实例 vue 实
例没有挂载
解决办法:
通过 Vue.nextTick(回调函数进行获取)

nextTick这个工具,让我们写的代码,无论在哪里写,都希望它是组件加载完了以后才运行

            beforeCreate(){
					//这个函数的回调函数是在组件加载完了才会执行
					this.$nextTick(()=>{
						console.log(this.msg)
					})
				}

五十三、Vue 渲染模板时怎么保留模板中的 HTML 注释呢?

在组件中将 comments 选项设置为 true,<template comments> ... <template>

五十四、vue-cli 提供了的哪几种脚手架模板?

vue-cli2.x 好像有个 simple 和完整版的
vue-cli3.x 提供了自定义装箱配置 可以选装
TypeScript
PWA
lint
e2e
css 预处理
router
vuex

1、webpack:

基于 webpack 和 vue-loader 的目录结构,而且支持热部署、代码检查、测试及 css 抽取。

2、webpack-simple:

基于 webpack 和 vue-loader 的目录结构。

3、browerify:

基于 Browerfiy 和 vueify(作用于 vue-loader 类似)的结构,支持热部署、代码检查及单元测

试。

4、browerify-simple:

基于 Browerfiy 和 vueify 的结构。

5、simple:

单个引入 Vue.js 的 index.html 页面。

这里我们主要会使用 webpack 作为常用脚手架,可以运行vue init webpack my-project 来生成项目。

五十五、vue-cli 工程中常用的 npm 命令有哪些?

1.npm install:下载 node_modules 资源包的命令
2.npm run dev: 启动 vue-cli 开发环境的 npm 命令(3.0 以下,脚手架 2 启动方式)
npm run serve:   启动 vue-cli 开发环境的 npm 命令(3.0 以上,脚手架 3 启动方式)
3.npm run build: vue-cli 生成 生产环境部署资源 的 npm 命令(常说的打包文件)
脚手架 2 打包,生成的是 build 文件
脚手架 3 打包,生成的是 dist 文件
4.serve build (脚手架 2,把你写好的项目打包,然后在本机测试,查看是否完整)
serve dist (脚手架 3,把你写好的项目打包,然后在本机测试,查看是否完整)
因为你最后直接给的是打包文件,交工之前直接测试一下,运行打包文件,查看项目是
否完整
5.npm run build--report:用于查看 vue-cli 生产环境部署资源文件大小的 npm 命令。
(脚手架 2、3 不一样)

五十六、在 Vue 中使用插件的步骤?

1、采用 ES6 的 import ... from ...语法或 CommonJS 的 require()方法引入插件
2 、 使 用 全 局 方 法 Vue.use( plugin ) 使 用 插 件 , 可 以 传 入 一 个 选 项 对 象
Vue.use(MyPlugin,{ someOption: true })

五十七、vue-cli 怎么解决跨域的问题?

1. vue.config.js 中设置 proxy,
比如'/api'开头的的请求将 被拦截到本地跨域服务器
module.exports = {
    devServer: {
        proxy: {
            '/api': {                              //需要代理的接口
                target: 'http://39.98.***.211',    //目标服务器
                changeOrigin: true,                //是否跨域
                pathRewrite: { '^/api': 'api' },   //重写
            },
        },
    },
}
2. 使用 cors,配合使用 cookie 和 session 保障数据安全
3. 本地服务器设置允许跨域的 headers,然后返回结果,从而解决跨域。

五十八、vue-router 路由有几种模式?说说它们的区别?

1.hash

#以及#后面的字符称之为hash,用window.location.hash读取;

特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。

hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

hash底层切换组件的方式是使用的老技术的Hash值,当地址栏的hash变化的时,切换了router-view渲染的组件,来”欺骗”用户,到达切换新网页的效果,hash值是不会发送给后端的,所以不需要后端配合

原理是 onhashchage 事件,可以在 window 对象上监听这个事件
window.onhashchange = function(event){ 
    console.log(event.oldURL, event.newURL)
     let hash = location.hash.slice(1) 
}

2.history

利用了 HTML5 History Interface 中新增的 pushState()和 replaceState()方法

history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。需要后台配置支持。如果刷新时,服务器没有响应响应的资源,会刷出 404。

所以,要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

history底层切换组件的方式是使用的H5的window.history的技术,当地址栏的history状态发生变化时,切换了router-view渲染的组件,来”欺骗“用户,到达切换新网页的效果

需要后端工程师配合  (写一个后端路由,并且与前端不一样)

const router=new VueRouter({
     mode:"hash",//"history"
	 routes:[{path:"/home",component:()=>import("./home.vue")},
	         {path:"/about",component:()=>import("./about.vue")}]
 })

3.抽象模式

五十九、vue-router 有哪几种导航钩子( 路由守卫guard )

路由守卫又称导航守卫,指是路由跳转前、中、后过程中的一些钩子函数。

官方解释是vue-router提供的导航守卫,要通过跳转或取消的方式来守卫导航。路由守卫分为三种,全局路由、路由独享组件内路由。

1、全局守卫 (3个)

router下的index.js里面的全局里==>和const router =new VueRouter({})同级

1.1 全局前置钩子router.beforeEach( (to,from,next)=>{} )

无论进入哪一个路由(只要每匹配一次路由),都要先调用这个函数

一定要以next() 结尾,否则会造成死循环

to:Route,代表要进入的目标,它是一个路由对象。
from:Route,代表当前正要离开的路由,从哪个页面来的,也是一个路由对象
next:Function,必须需要调用的方法,具体的执行效果则依赖 next 方法调用的参
next():进入管道中的下一个钩子,如果全部的钩子执行完了,则导航的状态就是 comfirmed(确认的)
next(false):终端当前的导航。如浏览器 URL 改变,那么 URL 会充值到 from路由对应的地址。
next(’/’)||next({path:’/’}):跳转到一个不同的地址。当前导航终 端,执行新的导航。
next 方法必须调用,否则钩子函数无法 resolved

1.2全局解析钩子router.beforeResolve(fn)

组件初始化,路由匹配成功

1.3全局后置钩子router.afterEach(fn)

后置钩子并没有 next 函数,也不会改变导航本身。

导航被确认,它可以解决很多问题:

比如:一般路由跳转以后用window.scroollTo把窗口调上去

当在A组件中划到了一定长度,然后跳转到B组件的页面,这个时候,B组件的滚动条也在A页面的位置,就可以使用它来写(window.scroollTo(0,0))让B组件回到顶部

2、路由独享的守卫 (1个)

写在router下的index.js里面的path,name、component的后面

2.1 beforeEnter(to,from,next)

路由初始化(组件未初始化)    参数与全局守卫参数一样

3、组件内部生命周期守卫 (3个)

写在组件里,比如login/index.vue里与methods同级

3.1 beforeRouteLeave

从该组件离开,导航离开该组件的对应路由时调用

可以访问组件实例 'this
可以进行缓存用户的选择,视频的暂停等

3.2 beforeRouteEnter(to,from,next)

路由已经跳过去了,组件被激活,使用不了this,故构造指定该next 可以接收一个回调函数接收当前vm 实例----路由传参获取参数,得到初始化数据

在渲染该组件的对应路由被 confirm 前调用
不能获取组件实例 ‘this’ ,因为当守卫执行前,组件实例还没被创建

3.3 beforeRouteUpdate(to,from,next)

组件重用时被调用----路由传参获取参数,避免增添watch 开销

在当前路由改变,但是该组件被复用时调用
例:对于一个动态参数的路径 /home/:id, /home/1 /home/2 之间跳转的时候
由于会渲染同样的 Home 组件,因此组件实例会被复用,而这个钩子就会在这个情况下被调用。
可以访问组件实例 'this'

导航守卫执行顺序:

beforeRouteLeave < beforeEach < beforeRouteUpdate < beforeEnter
< beforeRouteEnter < beforeResolve < afterEach

例如,用户在登录的状态下就能去到某页面,但是未登录则给你弹出一个未登录的提示。

路由守卫的目标是实现这样一个权限判断,在路由跳转之前,会触发一个函数.

let isLogin = false; //未登录
router.beforeEach((to,from,next) => {   //路由跳转“之前”先执行这里,决定是否跳转
    if (to.path === '/yourLogin' && isLogin === false) {
        alert("请登录”)
        next(false) //阻止路由跳转
    }else {
        next() //正常放行
    }
})

 路由守卫和vue的8个钩子函数的执行顺序:

1、缓冲页面(keep-alive:true)

初次进入页面
beforeRouteEnter(next()外) → beforeCreate → created → beforeMount → beforeRouteEnter( next()内 ) → mounted → activated → (离开页面时): beforeRouteLeave → deactivated
再次进入页面
beforeRouteEnter( next()外 ) → beforeRouteEnter( next()内 ) → activated


2、未缓存页面

beforeRouteEnter(next()外) → beforeCreate → created → beforeMount → beforeRouteEnter( next()内 ) → mounted → beforeRouteLeave → (离开页面时): beforeRouteLeave → beforeDestroy → destroyed

六十、对 router-link 的了解?

vue-router 插件的其中一个组件, 用于跳转路由,
类似于 a 标签, 它一般也会渲染成 a 标签, 但可通过 tag 来变更默认渲染元素, 通过 to 来跳转

router-link:相当于a标签,给我们提供跳转到某个路由的功能,如没有匹配到路由就会跳转失败: 

<router-link to="/login?name=karen&pwd=123">go</router-link>

 <router-link :to="{ path: '/login', query: { a: 1, b: 2 } }">go</router-link>
 
编程式跳转(JS跳转-编程式导航):

this.$router.push("/login?a=1&b=2")

this.$router.push({path:"/login",query:{name:"karen",pwd:123}})

两种跳转方法的获取参数的方法:(在create之后的所有地方)
this.$route.query 

a标签和router-link:的区别

1、a标签会请求服务器,然后刷新网页,因此用在链接外部网站

2、router-link:  它是渲染到页面也是a标签,但是只是改变了地址栏的网址并没有重新加载网页 ==>  路由的底层就是采用的history,去监听地址栏的变化,然后把当前APP组件中的router-view切换了,因此这种跳转用在网站内部的路由跳转

3、router-link: 可以传参,传对象,但是 a标签就不行

六十一、vue-router 响应路由参数(路由传值)的变化?

1、用 watch 检测

监听当前路由发生变化的时候执行
watch: { 
    $route(to, from){ 
        console.log(to.path) // 对路由变化做出响应
     }
 }

2.组件内导航钩子函数

beforeRouteUpdate(to, from, next){ 
// to do somethings 
}

六十二、$route 和 $router 的区别是什么?

1、router    为 VueRouter 的实例,是一个全局路由对象
包含了路由跳转的方法、钩子函 数等。
2、route    是路由信息对象 || 跳转的路由对象
每一个路由都会有一个 route 对象,是一 个局部对象
包含 path,params,hash,query,fullPath,matched,name 等路由信息参数。

六十三、vue-router 实现路由懒加载(动态路由)?

把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应的组件
即为路由的懒加载,可以加快项目的加载速度,提高效率
const router = new VueRouter({
     routes: [ 
    { path: '/home', 
    name: 'Home', 
    component:() = import('../views/home') } ] })

六十四、vue-router 的 query 与 params 传参方式有什么区别?

1.Params
只能使用 name,不能使用 path
参数不会显示在路径上
浏览器强制刷新参数会被清空
2. Query:
参数会显示在路径上,刷新不会被清空
name 可以使用 path 路径
接收参数:this.$route.params  this.$route.query

六十五、怎么定义 vue-router 的动态路由?怎么获取传过来的值?

动态路由的创建==>
主要是使用 path 属性过程中,使用动态路径参数,以冒号开头,如 下:
{ path: '/home/:id' name: 'home' components: home}
当匹配到/home下的路由时,
参数值会被设置到 this.$route.params 下,所以通过这个属性可以获取动态参数
this.$route.params.id

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

active-class 是 router-link 终端属性
用来做 选中样式的切换 ,当 router-link 标签被点击时将会应用这个样式
用法:(两种)
 1、直接在路由 js 文件中配置 linkActiveClass
export default new Router({ linkActiveClass: 'active', })
2、 在 router-link 中写入 active-class
active-class 选择样式时根据路由中的路径(to=“/home”)去匹配,然后显示
<router-link to="/home" class="menu-home" active-class="active">首页</router-lin k>
方法2,在标签里面写会导致一个问题==>
当在/my页面中,其实/也是被匹配到了,那么两个 active-class都被激活了
 
<router-link to="/" class="menu-home" active-class="active">
<router-link to="/my" class="menu-my" active-class="active">

解决方案:

1) 直接在路由js文件中配置linkActiveClass

export default new Router({ linkActiveClass: 'active', })

2) 在 router-link 中写入 exact

<router-link to="/" class="menu-home" active-class="active" exact>首页</router-li nk>

3)在路由中加入重定向

<router-link to="/" class="menu-home" active-class="active" exact>首页</router-li nk> 
{path: '/', redirect: '/home' }

六十七、MVVM 和 MVC 区别是什么?哪些场景适合?

1、基本定义
1.1)MVVM 基本定义
MVVM  ==>  Model-View-ViewModel ==> 模型-视图-视图模型
模型(Model) ==>后端传递的数据,
视图(View) ==>  所看到的页面,
视图模型(ViewModel) ==> mvvm 模 式的核心,它是连接 view 和 model 的桥梁。它有两个方向
1.1.1)一是将模型(Model)转化成视图(View),即将后端传递的数据转化成所看到
的页面,实现的方式是:数据绑定
1.1.2)二是将视图(View)转化成模型(Model),即将所看到的页面转化成后端的数据。 实现的方式是:DOM 事件监听
这两个方向都实现的,我们称之为数据的双向绑定
1.2)MVC 基本定义
MVC ==> Model-View- Controller ==> 即模型-视图-控制器。
M 和 V 指的意思和 MVVM 中的 M 和 V 意思一样。
C 即 Controller 指的是页面业务逻辑
使用 MVC 的目的 就是将 M 和 V 的代码分离。MVC 是单向通信。也就是 View 跟 Model,必须通过 Controller 来承上启下
2、两者之间的区别
MVC 和 MVVM 其实区别并不大,都是一种设计思想
 MVC 和 MVVM 的区别并不是 VM 完 全取代了 C,
只是在 MVC 的基础上增加了一层 VM,只不过是弱化了 C 的概念,
ViewModel 存在目的在于抽离 Controller 中展示的业务逻辑,而不是替代 Controller,
其它视图操作业务等还是应该放在 Controller 中实现,
也就是说 MVVM 实现的是业务逻 辑组件的重用, 使开发更高效,结构更清晰,增加代码的复用性
3、使用场景
主要就是 MVC 中 Controller 演变成 MVVM 中的 viewModel
MVVM 主要解决了 MVC 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验,vue 数据驱动, 通过数据来显示视图层而不是节点操作
场景:数据操作比较多的场景,需要大量操作 DOM 元素时,用 MVVM 的开发方式,会更加便捷,让开发者更多的精力放在数据的变化 上,解放繁琐的操作 DOM 元素

mvvm的框架主要有四种,分别为vue.js、react.js、avalon、angular.js

常见的MVC框架有struct2和spring

六十八、vue-router 是用来做什么的?原理是什么?

vue-router 路由,通俗来讲主要是来实现页面的跳转
通过设置不同的 path,向服务器发送的不同的请求,获取不同的资源。
主要组件:router-view、router-link。
“更新视图但不重新请求页面”是前端路由原理的核心之一
目前在浏览器环境中这一功能的实现主要有两种方式:
1、利用 URL 中的 hash(“#”)
2、利用 History interface 在 HTML5 中新增的方法

六十九、请说出路由配置项常用的属性及作用

路由配置参数:
1、path : 跳转路径
2、name:命名路由,比如后面使用跳转params传参只能使用name,还有keep-alive的匹配
3、component : 路径相对于的组件
4、children:子路由的配置参数(路由嵌套)
5、props:路由解耦
6、redirect : 重定向路由

七十、vuex 中 actions 和 mutations 有什么区别?

1、mutations
mutations 可以直接修改 state, 更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation
mutation中修改仓库数据,只能在同步代码中实现,只能通过提交 commit 调用
(尽量通过 Action 或 mapMutation 调用而非直接在组件中通过 this.$store.commit() 提交)
不要在异步函数中实现,否则会出现不刷新页面的情况。如果要异步的修改数据,就可以使用actions异步的提交mutations
2、actions
actions 是用来触发 mutations 的,它无法直接改变 state,它可以包含异步操作,它
只能通过 store.dispatch 触发

七十一、路由之间是怎么跳转的?有哪些方式?

1、<router-link to="需要跳转到页面的路径">
2、this.$router.push() 跳转到指定的 url,并在 history 中添加记录,点击回退返
回到上一个页面
3、this.$router.replace() 跳转到指定的 url,但是 history 中不会添加记录,点
击回退到上上个页面
4、this.$touter.go(n) 向前或者后跳转 n 个页面,n 可以是正数也可以是负数

七十二、简述 Vuex 的数据传递流程

1、当组件进行数据修改的时候:
调用 dispatch 来触发 actions 里面的方法,actions 就会触发commit 方法
2、commit 方法,当方法执行的时候会通过 commit 来触 mutations 里面的方法进行
数据的修改;
3、mutations 里面的每个函数都会有一个 state 参数,这样就可以在 mutations 里
面进行 state 的数据修改 ,当数据修改完毕后,会传导给页面,页面的数据也会发生改
总结: 调用dispatch--触发actions--触发commit--触发mutations--修改state

七十三、Vuex 的 5 个核心属性是什么?

1.state
Vuex 使用单一状态树,即每个应用将仅仅包含一个 store 实例,但单一状态树和模块
化并不冲突。存放的数据状态,不可以直接修改里面的数据。
2.mutations
mutations 定义的方法动态修改 Vuex 的 store 中的状态或数据。
3.getters
类似 vue 的计算属性,主要用来过滤一些数据。
4.action
actions 可以理解为通过将 mutations 里面处里数据的方法变成可异步的处理数据的
方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。
5.modules
项目特别复杂的时候,可以让每一个模块拥有自己的 state、mutation、action、getters,
使得结构非常清晰,方便管理

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

1、vuex是什么:
vuex 就是一个仓库,仓库里放了很多对象
只用来读取的状态集中放在 store 中;
改变状态的方式是提交 mutations(同步),异步逻辑需要acion异步提交mutations
2、使用方法:
在 main.js 引入 store,注入。新建了一个目录 store,….. export 。
3、使用场景:
  • 需要数据共享和行为进行拆分;

  • 复杂的异步逻辑,需要综合多个模块进行状态演进;

  • 需要用到第三方插件;

  • 需要综合考虑多个组件的生命周期,先后顺序,特定逻辑等等;

单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车

七十五、Vuex 的出现解决了什么问题?

主要解决了以下两个问题:
1、多个组件依赖于同一状态时,对于多层嵌套的组件的传参将会非常繁琐,并且对于
兄弟组件间的状态传递无能为力
2、来自不同组件的行为需要变更同一状态。
以往采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码

1.解决多个视图依赖同一状态的问题

2.解决多个组件共享状态时,单向数据流的简洁性很容易被破坏的问题

3.解决了数据很多的情况下,想要修改数据时,只需要在vuex中更改处理数据即可,不用去每个页面更改

4.使用路由传递参数时,由于参数过多会出现会导致400 等问题时,可以使用vuex解决

七十六、vue 如何自定义一个过滤器?

过滤器==> 对即将显示的数据做进一步的筛选处理,然后显示,过滤器并没有改变原来的数据,只是在原数据的基础上产生新的数据

过滤器可以用在两个地方:双花括号插值和 v-bind 表达式

过滤器可以串联,过滤器参数

vue中的过滤器分为两种:全局过滤器局部过滤器

全局过滤器

Vue.filter('formatePrice', (val) => {
    return val.toFixed(2)
})
// 使用
{
   
   {13.44 | formatePrice}} 

局部过滤器

<script>
	export default {
		data() {
			return {}
		},
		filters: { 
	    formateTime(val) {
	      let date = new Date(val)
	      let year = date.getFullYear()
	      let month = date.getMonth() + 1
	      let day = date.getDate()
	      return `${year}/${month}/${day}`
	    }
	  }
	}
</script>

七十七、vue.js 的两个核心是什么?

数据驱动:ViewModel,保证数据和视图的一致性。
组件系统:应用类 UI 可以看作全部是由组件树构成的。

七十八、Vue-router 怎么配置路由?

1、安装
npm i --save vue-router
2、引用并启用
import Vue from "vue"
import VueRouter from 'vue-router'
Vue.use(VueRouter)
3、配置路由文件
const routes = [
	// 首页--
	{
		path: '/',
		name: 'home',
		component: () => import("../views/wlf/Home.vue")
	}
]
4、视图加载的位置
默认 App.vue 文件中加<router-view></router-view>
5、跳转导航
<router-link to="/hello">helloword</router-link>(渲染出来的是 a 标签)

七十九、Vue 中动画如何实现?

1、哪个元素需要动画就给那个元素加 transition 标签
2、进入时 class 的类型分为以下几种
<name>-enter <name>-enter-active <name>-enter-to
3、离开时 class 的类型分为以下几种
<name>-leave <name>-leave-active <name>-leave-to
如果需要一组元素发生动画需要用标签<transition-group><transition-group>。

八十、什么是 vue 的计算属性?

在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且
可能多次使用的情况下,尽量采取计算属性的方式。
优点:
①使得数据处理结构清晰;
②依赖于数据,数据更新,处理结果自动更新;
③计算属性内部 this 指向 vm 实例;
④在 template 调用时,直接写计算属性名即可;
⑤常用的是 getter 方法,获取数据,也可以使用 set 方法改变数据;
⑥相较于 methods,不管依赖的数据变不变,methods 都会重新计算,但是依赖数据不变的时候 computed 从缓存中获取,不会重新计算
缺点:如果简单的运算也用计算属性,反而会增加资源消耗

 1.如果是修改了data中监听的某个的属性值 计算属性就会运行
2.如果是修改了data中监听的某个属性值内部的数据,计算属性就不会重新运行
比如:计算属性使用的是data中的一个数组,某个交互把数组内部的某个下标的值改了,但是这个数组没有改变,就不会触发计算属性
3.解决2的办法1:把修改后的数组重新赋值给data,让引用发生变化,来触发计算属性
3.解决2的办法2:赋值 JSON.parse(JSON.stringfy(data)) 转化为JSON字符串,再转为对象,相当于新创建了一个对象,数据是改变了

计算属性和方法的区别

1、计算属性

会把使用到的data中的属性缓存起来,防止页面发生大量重复计算,
提升js 运行效率,如果计算属性中使用到的data中那部分数据变了才会重新调用计算属性


2、methods方法

没有计算结果缓存起来,data任何数据发生改变,方法都会被重新调用一遍 
方法常常是作用的事件使用,计算属性常常是动态计算结果时使用

(刷新页面:模板重新渲染、重新取值)

八十一、Vue 如何去除 URL 中的# ?

vue-router 默认使用 hash 模式,所以在路由加载的时候,项目中的 URL 会自 带 “#”,
如果不想使用 “#”, 可以使用 vue-router 的另一种模式
history:newRouter ({ mode : 'history', routes: [ ]})
需要注意的是,当我们启用 history 模式的时候,由于我们的项目是一个单页面应用,
所以在路由跳转的时候,就会出现访问不到静态资源而出现 “404” 的情况,
这时候 就需要服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则 应该返回同一个 “index.html” 页面

八十二、自定义指令的几个钩子函数

1、bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化
设置。
2、inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文
档中)。
3、update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指
令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的
模板更新 。
4、componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
5、unbind:只调用一次,指令与元素解绑时调用。

八十三、vue 项目优化解决方案?

1.使用 mini-css-extract-plugin 插件抽离 css
2.配置 optimization 把公共的 js 代码抽离出来
3.通过 Webpack 处理文件压缩
4.不打包框架、库文件,通过 cdn 的方式引入
5.小图片使用 base64
6.配置项目文件懒加载
7.UI 库配置按需加载
8.开启 Gzip 压缩

八十四、 Vue.cli 项目中 src 目录每个文件夹和文件的用 法?

1、assets 文件夹是放静态资源
2、components 是放组件
3、router 是定义路由相关的配置
4、view 视图
5、app.vue 是一个应用主组件
6、main.js 是入口文件
(7、store==> vuex的文件)

八十五、关于 Vue.use() 的理解?

Vue.use() 是 Vue 的一个全局注册方法,主要用来注册插件,
默认第一个参数是 它接受的参数类型必须是 Function 或者是 Object,如是个对象,必须提供 install 方法,install 方法默认第一个参数为 Vue,其后的参数为注册时传入的arguments。如 果是 Function 那么这个函数就被当做 install 方法。同一个插件 Vue.use 会自动阻
止多次注册。除了在注册插件中使用 Vue.use 外,我们还可以在 directive 注册、
filters 注册、components 注册等条件下使用。
有的时候我们会遇到某些时候引入插件是并没有使用 Vue.use ,比如使用 axios
的时候,原因是 axios 没有 install 方法,所以也就不需要使用 Vue.use 来全局注册。

八十六、Vue-router 跳转和 location.href 有什么区别?

使用 location.href='/url'来跳转,简单方便,但是刷新了页面;
使用 history.pushState('/url'),无刷新页面,静态跳转;
引进 router,然后使用 router.push('/url')来跳转,使用了 diff 算法,实现了按需
加载,减少了 dom 的消耗。
其实使用 router 跳转和使用 history.pushState()没什么差别的,因为 vue-router
就是用了 history.pushState(),尤其是在 history 模式下。

八十七、vue 与 React 之间有什么区别?

相同点:
1、都支持服务器端渲染
2、都有 Virtual DOM,组件化开发,通过 props 参数进行父子组件数据的传递,都实现
webComponent 规范
3、数据驱动视图
4、都有支持 native 的方案,React 的 React native,Vue 的 weex
5、都有管理状态,React 有 redux,Vue 有自己的 Vuex(自适应 vue,量身定做)
不同点(区别):
1、React 严格上只针对 MVC 的 view 层,Vue 则是 MVVM 模式
2、virtual DOM 不一样,vue 会跟踪每一个组件的依赖关系,不需要重新渲染整个组
件树。而对于 React 而言,每当应用的状态被改变时,全部组件都会重新渲染,所以 react
中会需要 shouldComponentUpdate 这个生命周期函数方法来进行控制
3、组件写法不一样, React 推荐的做法是 JSX + inline style, 也就是把 HTML 和 CSS
全都写进 JavaScript 了,即'all in js';Vue 推荐的做法是 webpack+vue-loader 的单文
件组件格式,即 html,css,jd 写在同一个文件
4、数据绑定: vue 实现了数据的双向绑定,react 数据流动是单向的
5、state 对象在 react 应用中不可变的,需要使用 setState 方法更新状态;在 vue
中,state 对象不是必须的,数据由 data 属性在 vue 对象中管理;

八十八、使用 vue 后怎么针对搜索引擎做 SEO 优化?

1. SSR 服务器渲染,即单页面后台渲染
2.vue-meta-info 与 prerender-spa-plugin 预渲染
3. 使用 nuxt,但是 nuxt 部署有一定局限性,需要服务器配置 node 环境
4. 使用 Phantomjs 针对爬虫做处理。

八十九、什么是虚拟 DOM?

虚拟 dom 是相对于浏览器所渲染出来的真实 dom 的,在 react,vue 等技术出现之前,
我们要改变页面展示的内容只能通过遍历查询 dom 树的方式找到需要修改的 dom 然后
修改样式行为或者结构,来达到更新 ui 的目的。
这种方式相当消耗计算资源,因为每次查询 dom 几乎都需要遍历整颗 dom 树,如果
建立一个与 dom 树对应的虚拟 dom 对象( js 对象),以对象嵌套的方式来表示 dom 树,
那么每次 dom 的更改就变成了 js 对象的属性的更改,这样一来就能查找 js 对象的属
性变化要比查询 dom 树的性能开销小。

九十、写过 vuex 中 store 的插件吗?

Vuex 的 store 接受 plugins 选项,这个选项暴露出每次 mutation 的钩子。Vuex 插
件就是一个函数,它接收 store 作为唯一参数
const myPlugin = store => { // 当 store 初始化后调用 store.subscribe((mutation, state) => { // 每次 mutation 之后调用 // mutation 的格式为 { type, payload } }); };
然后像这样使用:
const store = new Vuex.Store({ // ... plugins: [myPlugin] });

九十一、vue $nextTick 作用是什么?

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,
获取更新后的 DOM。简单的说就是再 DOM 操作时,vue 的更新是异步的,$nextTick 是
用来知道什么时候 DOM 更新完成的。

九十二、vue 中怎么重置 data?

Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对
象,说明:
this.$data 获取当前状态下的 data
this.$options.data()获取该组件初始状态下的 data。
Object.assign(this.$data, this.$options.data())将当前状态的 data 重置为初始
状态

九十三、什么是函数式组件?

函数式组件:
需要提供一个 render 方法, 接受一个参数( createElement 函数), 方法内根据业务逻辑,通过
createElement 创建 vnodes ,最后 return vnodes
createElement 函数, 三个参数, 第一个参数是 html 标签或自定义组件,第二个参
数一个 obj(包含 props, on...等等), 第三个参数 children(通过 createElement 构
建, 或者字符串)

九十四、对 vue 的 extend(构造器)的理解,它主要是用来做什么的?

extend 的作用是继承当前的 Vue 类,传入一个 extendOption 生成一个新的构造函数。
在 extend 的时候会进行 mergeOption,融合 Vue 原型上的 baseOption,所以 extend 出来
的子类也能使用 v-model、keep-alive 等全局性的组件。
作用是生成组件类。在挂载全局组件和设置了 components 属性的时候会使用到。在生
成 DOM 的时候会 new 实例化挂载。

九十五、如果将 axios 异步请求同步化处理?

使用 asyns/await 将 axios 异步请求同步化:
1. 当 axios 请求拿到的数据在不同场景下做相同的处理时:
2. 当 axios 请求拿到的数据在不同场景下做不同的处理时:

九十六、SPA 单页面的实现方式有哪些?

1.监听地址栏中 hash 变化驱动界面变化
2.用 pushsate 记录浏览器的历史,驱动界面发送变化
3.直接在界面用普通事件驱动界面变化
它们都是遵循同一种原则:div 的显示与隐藏

九十七、如何引入 scss?引入后如何使用?

1.安装 scss 依赖包:
npm install sass-loader --save-dev npm install node-sass --save-dev
2.在 build 文件夹下修改 webpack.base.conf.js 文件:
3.在 module 下的 rules 里添加配置,如下:
{ test: /\.scss$/, loaders: ['style', 'css', 'sass'] }
4.应用:
在 vue 文件中应用 scss 时,需要在 style 样式标签上添加 lang="scss",即<style
lang="scss">

九十八、vue 实例挂载的过程是什么?

1.render, 没有则去编译
2.编译 vdom
3.对实例进行 watch

九十九、Vue minix(混入)的用法?

minix(混入) 是 Vue 中的高级用法,混入 (mixin) 提供了一种非常灵活的方式,
来分发 Vue 组件中的可复用功能。比如我们做一个下拉加载,很多组件都需要用到下拉
加载,我们就可以把下拉加载封装成一个 minix,然后需要下拉加载功能的页面都去导入
这个 minix,minix 里面的属性或者方法就会被混合到当前组件本身的属性上。
简单的说,minix B 有个 C 方法(下拉加载),页面 A 需要下拉加载于是就导入了
minix B,这时候页面 A 也就拥有了 C 方法。如果页面 A 本身有个 D 方法,这时页面 A
就会既有 C 方法也有本身的 D 方法。

一百、Vue 中如何实现一个虚拟 DOM?说说你的思路

首先要构建一个 Vnode 的类,DOM 元素上的所有属性在 Vnode 类实例化出来的
对象上都存在对应的属性。例如 tag 表示一个元素节点的名称,text 表示一个文本节
点的文本,chlidren 表示子节点等。将 Vnode 类实例化出来的对象进行分类,例如注
释节点、文本节点、元素节点、组件节点、函数式节点、克隆节点。
然后通过编译将模板转成渲染函数 render,执行渲染函数 render,在其中创建
不同类型的 Vnode 类,最后整合就可以得到一个虚拟 DOM(vnode),最后通过 patch 将
vnode 和 oldVnode 进行比较后,生成真实 DOM

一百零一、Vue 中操作 data 中数组的方法中哪些可以触发视图更新, 哪些不可以,不可以的话有什么解决办法?

1、可以被改变的
push()、pop()、shift()、unshift()、splice()、sort()、reverse()这些方法
会改变被操作的数组;
2、不可以改变的
filter()、concat()、 slice()这些方法不会改变被操作的数组,并且返回一个
新的数组,以方法都可以触发视图更新
3、解决方案
1)、利用索引直接设置一个数组项,例:this.array[index] = newValue,直接
修改数组的长度,例:this.array.length = newLength
2)、以上两种方法不可以触发视图更新
a)可以使用 this.$set(this. array, index, newValue),this.array.splice
(index,1,newValue)
b)可以使用 this.array.splice(newLength)

一百零二、在 Vue 实例中编写生命周期 hook 或其他 option/ propertie 时,为什么不使用箭头函数?

箭头函数自己没有定义 this 上下文,而是绑定到其父函数的上下文中,当你在 Vue 程
序中使用箭头函数(=>)时,this 关键字病不会绑定到 Vue 实例,因此会引发错误,
所以强烈建议改用标准函数声明

一百零三、is 这个特性你有用过吗?主要用在哪些方面?

1、动态组件
<component :is="componentName"></component>, componentName 可以是在本
页面已经注册的局部组件名和全局组件名,也可以是一个组件的选项对象。 当控制
componentName 改变时就可以动态切换选择组件
2、is 的用法
有些 HTML 元素,诸如 <ul>、<ol>、<table>和<select>,对于哪些元素可以出
现在其内部是有严格限制的,而有些 HTML 元素,诸如 <li>、<tr> 和 <option>,只能
出现在其它某些特定的元素内部
<ul>
<card-list></card-list>
</ul>
所以上面<card-list></card-list>会被作为无效的内容提升到外部,并导致最终
渲染结果出错。应该这么写:
<ul>
<li is="cardList"></li>
</ul>

一百零四、怎么给 vue 定义全局的方法

两种方式:
第一种:挂载到 Vue 的 prototype 上。把全局方法写到一个文件里面,然后 for 循环
挂载到 Vue 的 prototype 上,缺点是调用这个方法的时候没有提示
Object.keys(tools).forEach(key => {
Vue.prototype[key] = tools[key]
})
第二种:利用全局混入 mixin,因为 mixin 里面的 methods 会和创建的每个单文件组
件合并。这样做的优点是调用这个方法的时候有提示

一百零五、在.vue 文件中 style 是必须的吗?那 script 是必须的吗?

都不是必须的。
如果是普通组件那么只能是一个静态 html,如果是函数式组件, 那么可以直接使用
props 等函数式组件属性。

一百零六、`<template></template>`有什么用?

包裹嵌套其它元素,使元素具有区域性,自身具有三个特点:
1.隐藏性:不会显示在页面中
2.任意性:可以写在页面的任意地方
3.无效性: 没有一个根元素包裹,任何 HTML 内容都是无效的

一百零七、vue 的:class 和:style 有几种表示方式?

:class 绑定变量 绑定对象 绑定一个数组 绑定三元表达式
:style 绑定变量 绑定对象 绑定函数返回值 绑定三元表达式

一百零八、删除数组用 delete 和 Vue.delete 有什么区别?

delete:只是被删除数组成员变为 empty / undefined,其他元素键值不变
Vue.delete:直接删了数组成员,并改变了数组的键值(对象是响应式的,确保删除
能触发更新视图,这个方法主要用于避开 Vue 不能检测到属性被删除的限制)

一百零九、动态添加(注册)路由 addRoute

以前是 addRoutes,现在变为了addRoute,没有了s

添加一条新的路由记录作为现有路由的子路由。

如果路由有一个name,并且已经有一个与之名字相同的路由,它会先删之前的路由。

addRoute(parentName:string|symbol,route:RouteRecordRaw):()=>void(案例未写)

addRoute(route:RouteRecordRaw):()=>void

 一般用于数据处理后进行动态的添加/注册路由

比如:当输入账号的密码之后,进行判断,去动态的添加路由,是用户界面还是管理页面,这样这个账号才可以跳转相应的页面

// addRoute(route:RouteRecordRaw):()=>void   的  两种方式:

//1、在router下的index.js中
router.addRoute({   //动态注册(添加)路由:
    path: '/car2',
    name: 'car2',
    component: () => import("../views/car/index.vue")
})

//2、在mehtods中
    methods: {
            addro() {
                console.log(123445)
                //
                this.$router.addRoute({
                    path: "/car",
                    component: () => import("../car/index.vue")
                })
            }
        }

猜你喜欢

转载自blog.csdn.net/qq_52301431/article/details/127288339