# 1. jQuery 和 Vue 的区别

  1. 数据和视图的分离,解耦(开放封闭原则,对修改封闭,对扩展开放);
  2. 以数据驱动视图,只关心数据变化,DOM操作被封装。

# 2. 如何理解MVVM?

MVC:M-Model数据,V-View 视图、界面,C-Controller控制器,逻辑处理 MVVM:Vm是一个桥,ViewModel 主要通过DOM ListenerData Bindings 连接ViewModel

1)三大框架都是数据驱动型的框架 2)vue及angular是双向数据绑定;react是单向数据绑定。React貌似使用的也是Object.defineProperty 监控数据,只是没有进一步把表单控件的事件封装进 v-model 3)Vuex、Redux 都是单项数据绑定的,即 M 的变化可以自动更新到 V,但 V 的变化必须手动触发事件更新到 M,这种单项数据绑定使数据更易于跟踪管理和维护。

# 3. Vue 三要素

  • 响应式(vue如何监听到data 的每个属性变化)
  • 模板引擎(模板如何被解析,指令如何处理)
  • 渲染(模板如何被渲染成html,渲染过程)

# 4. 什么是模板

  • Html是静态的、没有逻辑,模板是动态的、有逻辑
  • 模板:字符串;有逻辑;嵌入JS变量
  • 模板必须转换为JS代码 [有逻辑(JS才能实现)、转为html渲染页面(JS才能实现)]

# 5. Vue的整个实现流程

  1. 解析模板成render函数
  2. 响应式开始监听
  3. 首次渲染,显示页面,且绑定依赖
  4. data属性变化,触发rerender

# 6. computed和watch的区别

# 6.1. computed 特性

  1. 是计算值
  2. 应用:就是简化tempalte里面{{}}计算和处理props$emit的传值
  3. 具有缓存性,页面重新渲染值不变化时,计算属性会立即返回之前的计算结果,而不必再次执行函数

# 6.2. watch 特性

  1. 是观察的动作
  2. 应用:监听props$emit或本组件的值执行异步操作
  3. 无缓存性,页面重新渲染时值不变化也会执行

# 7. methods,watch,computed的区别

  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
  2. methods方法表示一个具体的操作,主要书写业务逻辑;
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体

# 8. v-ifvs v-show

  1. v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  2. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  3. 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS(display) 进行切换。
  4. 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

# 9. vue双向绑定原理

vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)。

# 10. 为什么vue组件的属性,有的需要加冒号“:”,有的不用?

加冒号的,说明后面的是一个变量或者表达式,没加冒号的后面就是对应的字符串字面量

# 11. 理解 vue 修饰符sync

sync会被扩展为一个自动更新父组件属性的 v-on 监听器。

示例代码如下:

<comp :foo.sync="bar"></comp>

会被扩展为:

<comp :foo="bar" @update:foo="val => bar = val"></comp>

当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:

this.$emit('update:foo', newValue)

# 12. 为什么在 vue 的组件中,data 要用 function 返回对象呢?

  • 因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
  • 如果不用function return 每个组件的data都是内存的同一个地址,那一个数据改变其他也改变了。 用function return 其实就相当于申明了新的变量,相互独立,自然就不会有这样的问题

# 13. Vue事件修饰符——.prevent 和.passive

prevent 是拦截默认事件,passive是不拦截默认事件。

# 13.1. prevent

  • 某些标签拥有自身的默认事件,如a[href="#"]button[type="submit"] 这种标签在冒泡结束后会开始执行默认事件。注意默认事件虽然是冒泡后开始,但不会因为stop阻止事件传递而停止。

# 13.2. passive

  • passive这个修饰符会执行默认方法。你们可能会问,明明默认执行为什么会设置这样一个修饰符。这就要说一下这个修饰符的本意了。
  • 【浏览器只有等内核线程执行到事件监听器对应的JavaScript代码时,才能知道内部是否会调用preventDefault函数来阻止事件的默认行为,所以浏览器本身是没有办法对这种场景进行优化的。这种场景下,用户的手势事件无法快速产生,会导致页面无法快速执行滑动逻辑,从而让用户感觉到页面卡顿。】
  • 通俗点说就是每次事件产生,浏览器都会去查询一下是否有preventDefault阻止该次事件的默认动作。我们加上passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作。

这里一般用在滚动监听,@scoll@touchmove 。因为滚动监听过程中,移动每个像素都会产生一次事件,每次都使用内核线程查询prevent会使滑动卡顿。我们通过passive将内核线程查询跳过,可以大大提升滑动的流畅度。

注:passiveprevent冲突,不能同时绑定在一个监听器上。

# 14. 覆盖elementui样式的几种办法

  • /deep/ 标签,例如 /deep/ .class{ 要覆盖的样式 }
  • 可以在这个写scopestyle标签下面再写一个style标签,专门写要覆盖的样式就好了 。
  • index.html中引入一个外部样式,进行覆盖

# 15. $router$route的区别

  • $router 路由器
  • $route 单个路由页面

# 16. Vue 中父子组件执行的先后顺序

  • “父亲”先开始自己的created
  • 然后“儿子”开始自己的createdmounted
  • 最后“父亲”再执行自己的mounted

# 17. Vue 创建全局变量和方法

Vue 创建全局变量和方法有很多种,不过在这我推荐使用先新建一个js文件,这个文件主要就是写一个对象,这个对象直接带属性和方法即可,然后在main.js引入,引入后再用Vue.prototype把引入的文件直接挂接到vue的原型上。 例如: 新建的js文件内容:

//在文件的开始先定义一个对象
const  aa = {}

// 要全局的变量的话
aa.name = '张三'

// 定义方法
aa.bb= function ( ) {
   
};

export default aa

main.js中:

// 引入封装好的js文件的路径
import aa from './***/***/***'

// 把全局js挂接到vue原型上
Vue.prototype.$aa = aa

这样就能用了 在 vue 实例化上要用变量的话就话就直接this.aa.name,用方法的话就this.aa.bb()这样就OK了

# 18. cli-3.0环境变量

cli-3.0总共提供了四种方式来制定环境变量:

  • 在根目录添加.env文件,配置所有情况下都会用到的配置
  • 在根目录添加.env.local文件,配置所有情况下都会用到的配置,与.env的区别是只会在本地,该文件不会被git跟踪。
  • 在根目录添加.env.[mode]文件,配置对应某个模式下的配置,比如:.env.development来配置开发环境的配置。
  • 在根目录添加.env.[mode].local文件,配置对应某个模式下的配置,与.env.[mode]的区别也只是会在本地生效,该文件不会被git跟踪。

在文件中,我们只需要以key=value的方式就可以设置变量了。 例如:

FOO=bar
VUE_APP_SECRET=secret

# 19. 环境变量的使用

设置完环境变量之后就可以在我们的项目中使用这两个变量了。不过还需要注意的是在项目的不同地方使用,限制也不一样。

  1. 在项目中,也就是src中使用环境变量的话,必须以VUE_APP_开头。例如我们可以在main.js中直接输出:
console.log(process.env.VUE_APP_SECRET)
  1. webpack配置中使用,没什么限制,可以直接通过process.env.XXX来使用
  2. public/index.html中使用的:分三类:(没怎么用过)
  • <%= VAR %> 用于非转换插值 例如:
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
  • <%- VAR %> 用于HTML转义插值
  • <% expression %> 用于JavaScript控制流

# 20. slot的理解

React中的组件<Acomp></Acomp>中间是空的,而Vue允许在里面加入内容,比如<Acomp>Mike</Acomp>,那么Mike就会插入到组件Acomp中的<slot></slot>中。

# 具名插槽

具名插槽就是组件里面有多个<slot></slot>

# 作用域插槽

作用域插槽就是想在使用组件的时候,获取其slotdata,如:

组件定义:

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

绑定在 <slot>元素上的 attribute 被称为插槽 prop

使用:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>