# 补充

# 39.双向绑定的定义

  • 一般只有 UI 表单控件才存在双向数据绑定,非 UI 表单控件只有单向数据绑定。
  • 单向数据绑定是指:M 的变化可以自动更新到 ViewModel,但 ViewModel 的变化需要手动更新到 M(通过给表单控件设置事件监听)
  • 双向数据绑定是指:M 的变化可以自动更新到 ViewModel,ViewModel 的变化也可以自动更新到 M

# 40.探索 Vue3 响应式原理 (opens new window)

# 41.Vue 指令大全(超详细) (opens new window)

# 42.vue-loader 原理分析 (opens new window)

如何让 CSS 旨在当前组件中起作用?

当前组件的 < style>标签修改为< style scoped>

# 43.Vue template 到 render 的过程

  1. 调用 parse 方法将 template 转化为 ast(抽象语法树, abstract syntax tree)
  2. 对 ast 中的静态节点做优化。如果为静态节点,他们生成的 DOM 永远不会改变,这对运行时模板更新起到了极大的优化作用。
  3. 由优化后的 ast 生成 render code,并通过 new Function 生成 render function. render function 的返回值是 VNode,VNode 是 Vue 的虚拟 DOM 节点,里面有(标签名,子节点,文本等等)

# 44.批量异步更新策略

vue data 中某一个属性的值发生改变后,视图不会立即同步执行重新渲染。

Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。

Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化, Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环”tick”中,Vue 刷新队列并执行实际(已去重的)工作,从而避免不必要的计算和 DOM 操作。

# 45.vue-router 如何定义嵌套路由

通过 children 数组:

const router = new VueRouter({
  routes: [
    {
      path: '/parentPage',
      component: testPage,
      children: [
        {
          path: '/childrenA',
          component: childrenComponentA
        },
        {
          path: '/childrenB',
          component: childrenComponentB
        }
      ]
    },
    {
      // 其他和parentPage平级的路由
    }
  ]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 46.$route和$router 的区别

  1. $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。
  2. $router 是“路由实例”对象包括了路由的跳转方法,钩子函数等

路由之间跳转的方式

  1. 声明式(标签跳转)
  2. 编程式( js 跳转)

active-class 是哪个组件的属性

vue-router 模块 的 router-link 组件

# 47.说说你对 SPA 单页面的理解,它的优缺点分别是什么?

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。

优点:

  • 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
  • 基于上面一点,SPA 相对对服务器压力小;
  • 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;

缺点:

  • 初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
  • 前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
  • SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

# 48.Class 与 Style 如何动态绑定?

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

  • 对象语法:
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>

data: {
  isActive: true,
  hasError: false
}
1
2
3
4
5
6
  • 数组语法:
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}
1
2
3
4
5
6

Style 也可以通过对象语法和数组语法进行动态绑定:

  • 对象语法:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

data: {
  activeColor: 'red',
  fontSize: 30
}
1
2
3
4
5
6
  • 数组语法:
<div v-bind:style="[styleColor, styleSize]"></div>

data: {
  styleColor: {
     color: 'red'
   },
  styleSize:{
     fontSize:'23px'
  }
}
1
2
3
4
5
6
7
8
9
10

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

由于 JavaScript 的限制,Vue 不能检测到以下数组的变动:

  • 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  • 当你修改数组的长度时,例如:vm.items.length = newLength

为了解决第一个问题,Vue 提供了以下操作方法:

// 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
2
3
4
5
6

为了解决第二个问题,Vue 提供了以下操作方法:

// Array.prototype.splice
vm.items.splice(newLength)
1
2

# 51.Vue 的两个核心是什么

1、数据驱动,也叫双向数据绑定。

2、组件系统。

# 52.vue3 的双向绑定的原理

# 53.vue2 生命周期有哪些

  • beforeCreate: 组件实例刚被创建, 组件属性计算之前, 如 data 属性等
  • created: 组件实例创建完成, 属性已绑定, 但 DOM 还未生成, $el 属性还不存在
  • beforeMount: 模版编译/挂载之前
  • mounted: 模版编译/挂载之后(不保证组件已在 document 中)
  • beforeUpdate: 组件更新之前
  • updated: 组件更新之后
  • activated: for *keep-alive*, 组件激活时调用
  • deactivated: for *keep-alive*, 组件移除时调用
  • beforeDestory: 组件销毁前调用
  • destory: 组件销毁后调用

# 54.Vue 中的$nextTick 有什么作用

Vue 中的$nextTick 有什么作用 (opens new window)

# 55.v-ifv-show 的区别

v-ifv-show 的区别 (opens new window)

# 56.vue 常用的修饰符

  • 输入过滤 .lazy,.number,.trim
  • 事件修饰符 .stop,.prevent,.capture,.self
  • 按键修饰符

在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit" />
1
2

记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:

<!-- 同上 -->
<input v-on:keyup.enter="submit" />

<!-- 缩写语法 -->
<input @keyup.enter="submit" />
1
2
3
4
5

全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

# 系统修饰键

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。

  • .ctrl
  • .alt
  • .shift
  • .meta

例如:

<!-- Alt + C -->
<input @keyup.alt.67="clear" />

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
1
2
3
4
5

# 57.虚拟 DOM 的作用

Virtual DOM 本质上是 JavaScript 对象,是对实际 DOM 的抽象,是对实际 DOM 更加轻量级的描述.

既然我们已经有了 DOM,为什么还需要额外加一层抽象?

  • 尽可能少地操作 DOM 的次数

首先,我们都知道在前端性能优化的一个秘诀就是尽可能少地操作 DOM,不仅仅是 DOM 相对较慢,更因为频繁变动 DOM 会造成浏览器的回流或者重回,这些都是性能的杀手,因此我们需要这一层抽象,在 patch 过程中尽可能地一次性将差异更新到 DOM 中,这样保证了 DOM 不会出现性能很差的情况.

  • 无须手动操作 DOM,提高代码质量

其次, 现代前端框架的一个基本要求就是无须手动操作 DOM,一方面是因为手动操作 DOM 无法保证程序性能,多人协作的项目中如果 review 不严格,可能会有开发者写出性能较低的代码,另一方面更重要的是省略手动 DOM 操作可以大大提高开发效率.

  • 更好的跨平台

最后,也是 Virtual DOM 最初的目的,就是更好的跨平台,比如 Node.js 就没有 DOM,如果想实现 SSR(服务端渲染),那么一个方式就是借助 Virtual DOM,因为 Virtual DOM 本身是 JavaScript 对象.

参考链接:

  1. https://juejin.cn/post/6961222829979697165?share_token=0de92df3-3d8b-44d6-9978-1a628c2081a0
  2. https://jishuin.proginn.com/p/763bfbd59fde
  3. https://juejin.cn/post/6844903918753808398

在线客服